动态严格如何在ElasticSearch中应用

Tch*_*uan 1 elasticsearch

我正在使用ElasticSearch 2.3.3。

我有以下映射:

"mappings": {
  "entries": {
    "dynamic": "strict",
    "properties": {
      "Data": {
        "properties": {
          "Age": {
            "type": "long"
          },
          "BirthDate": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss.SSS"
          },
          "Cash": {
            "type": "boolean"
          },
          "Cheque": {
            "type": "boolean"
          },
          "Comments": {
            "type": "string"
          },
          "CreditCard": {
            "type": "boolean"
          },
          "FirstName": {
            "type": "string",
            "index": "not_analyzed"
          },
          "Gender": {
            "type": "string",
            "index": "not_analyzed"
          },
          "LastName": {
            "type": "string",
            "index": "not_analyzed"
          }
        }
      },
      "MetaInfo": {
        "properties": {
          "CreatedDate": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss.SSS"
          },
          "FormId": {
            "type": "string",
            "index": "not_analyzed"
          },
          "FormName": {
            "type": "string",
            "index": "not_analyzed"
          },
          "FormVersion": {
            "type": "integer"
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意,我已经"dynamic" : "strict"扎根。

我是否必须为所有级别的嵌入式对象指定“ dynamic”:“ strict”?换句话说,如果我在根级别设置“ dynamic”:“ strict”,那么它也适用于嵌入式对象吗?

文档尚不清楚。

Jay*_*ard 6

Elasticsearch“权威指南”在谈到动态映射时说:

动态设置可以应用于根对象或类型对象的任何字段。您可以在默认情况下将dynamic设置为strict,但是仅对特定的内部对象启用它。

关于该值的继承尚不清楚。因此,让我们尝试一下Elasticsearch 2.4.0(当前版本)中的所有选项,看看会发生什么:

限制动态映射的选项:

1.全球

index.mapper.dynamic: false在文件中设置属性,elasticsearch.yml它将应用于系统中的所有索引,例如:

index.mapper.dynamic: false
Run Code Online (Sandbox Code Playgroud)

因此,在创建和使用索引时:

$ curl -XPUT localhost:9200/test
  {"acknowledged":true}
$ curl -XPUT localhost:9200/test/test/1 -d '{"foo":"bar"}'
  {"error":{"root_cause":[{"type":"type_missing_exception","reason":"type[test] missing","index":"test"}],"type":"type_missing_exception","reason":"type[test] missing","index":"test","caused_by":    {"type":"illegal_state_exception","reason":"trying to auto create mapping, but dynamic mapping is disabled"}},"status":404}
$ curl -XPUT localhost:9200/test/test/1 -d '{"foo": {"bar": 123}}'
  ...same error
Run Code Online (Sandbox Code Playgroud)

因此,对于任何级别的对象(根或嵌套),都会显示此错误。 请注意,此设置的值为true/ false而不是strict(将被视为无效值)。

2.每个索引设置

您可以将相同的设置应用于一个特定的索引,只需index.mapper.dynamic: false在索引创建时将其添加到索引设置中,它将应用于所有类型以及该索引中对象的所有嵌套级别(这很好地涵盖了您的情况)。

例如,创建索引时:

$ curl -XPUT localhost:9200/test -d '{
      "index.mapper.dynamic": false}
  }'
  {"acknowledged":true}
Run Code Online (Sandbox Code Playgroud)

如果在映射中不存在该字段,则使用时会出错:

$ curl -XPUT localhost:9200/test/test/1 -d '{"foo":"bar"}'
  {"error":{"root_cause":[{"type":"type_missing_exception","reason":"type[test] missing","index":"test"}],"type":"type_missing_exception","reason":"type[test] missing","index":"test","caused_by":{"type":"illegal_state_exception","reason":"trying to auto create mapping, but dynamic mapping is disabled"}},"status":404} 
$ curl -XPUT localhost:9200/test/test/1 -d '{"foo": {"bar": 123}}'
  ...same error
Run Code Online (Sandbox Code Playgroud)

因此,对于任何级别的对象(根或嵌套),都会显示此错误。 请注意,此设置的值为true/ false而不是strict

3.默认为一个索引内的类型映射

如果添加"dynamic": "strict"_default_类型映射以应用于以后创建的所有类型:

创建索引时:

$ curl -XPUT localhost:9200/test -d '{
    "mappings": {
        "_default_": {
           "dynamic": "strict"
        }
    } 
}'
  {"acknowledged":true}
Run Code Online (Sandbox Code Playgroud)

尝试添加新的未映射字段时,将给您一个稍微新的错误:

$ curl -XPUT localhost:9200/test/test/1 -d '{"foo":"bar"}'
  {"error":{"root_cause":[{"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [foo] within [test] is not allowed"}],"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [foo] within [test] is not allowed"},"status":400}
Run Code Online (Sandbox Code Playgroud)

进行相同的操作,但向类型添加一些字段:

$ curl -XPUT localhost:9200/test -d '{
    "mappings": {
       "_default_": {
          "dynamic": "strict"
       },
       "test": {
           "properties": {
               "foo": { "type": "string" },
               "bar": { 
                      "type": "nested",
                      "properties": {
                         "bell": { "type": "string" }
                      }
               }
           }
       }
     }
   }'
Run Code Online (Sandbox Code Playgroud)

当尝试不同的尝试时,将导致:

$ curl -XPUT localhost:9200/test/test/1 -d '{"foo": "asb"}'
   {"_index":"test","_type":"test","_id":"1","_version":1,"_shards":{"total":1,"successful":1,"failed":0},"created":true}
$ curl -XPUT localhost:9200/test/test/1 -d '{"bar": { "bell": "abc" } }'
   {"_index":"test","_type":"test","_id":"1","_version":2,"_shards":{"total":1,"successful":1,"failed":0},"created":false}
$ curl -XPUT localhost:9200/test/test/1 -d '{"bar": { "dog": "abc" } }'
  {"error":{"root_cause":[{"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [bar] is not allowed"}],"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [bar] is not allowed"},"status":400}
Run Code Online (Sandbox Code Playgroud)

因此,所有级别都是严格的,包括嵌套对象!

4.在索引映射的对象内

这是您上面直接询问的内容,看起来像:

$ curl -XPUT localhost:9200/test -d '{
  "mappings": {
    "test": {
      "dynamic": "strict",
      "properties": {
        "foo": {
          "type": "string"
        },
        "bar": {
          "type": "nested",
          "properties": {
            "bell": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

当尝试在嵌套级别添加不存在的字段时:

$ curl -XPUT localhost:9200/test/test/1 -d '{"bar": { "dog": "abc" } }'
  {"error":{"root_cause":[{"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [bar] is not allowed"}],"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [bar] is not allowed"},"status":400}
Run Code Online (Sandbox Code Playgroud)

因此,严格设置再次继承到嵌套对象中。如果需要,可以在嵌套级别覆盖设置以从该点向下更改其含义:

$ curl -XPUT localhost:9200/test -d '{
  "mappings": {
    "test": {
      "dynamic": "strict",
      "properties": {
        "foo": {
          "type": "string"
        },
        "bar": {
          "type": "nested",
          "dynamic": true,
          "properties": {
            "bell": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}'
Run Code Online (Sandbox Code Playgroud)

结果为:

$ curl -XPUT localhost:9200/test/test/1 -d '{"bar": { "dog": "abc" } }'
  {"_index":"test","_type":"test","_id":"1","_version":1,"_shards":{"total":1,"successful":1,"failed":0},"created":true}
Run Code Online (Sandbox Code Playgroud)

但仍然无法在顶层允许动态新字段:

$ curl -XPUT localhost:9200/test/test/1 -d '{"dog": "abc" }'
  {"error":{"root_cause":[{"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [test] is not allowed"}],"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [dog] within [test] is not allowed"},"status":400}
Run Code Online (Sandbox Code Playgroud)

摘要

最快的答案是,可以禁用动态映射的所有方式都向下传播到所有级别的嵌套。您会发现旧的错误报告,旧的论坛消息以及其他示例,它们说明或暗示相反的含义,但对于Elasticsearch 2.4.0(我在此测试中使用的)而言,上述说法仍然适用。