如何在ElasticSearch

时间:2016-09-02 16:41:10

标签: 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"
          }
        }
      }
    }
  }
}

请注意,我已将"dynamic" : "strict"放在根目录。

我是否必须指定"动态":"严格"到所有级别的嵌入对象?换句话说,如果我设置"动态":"严格"在根级别,它是否也适用于嵌入式对象?

文档不清楚。

1 个答案:

答案 0 :(得分:5)

Elasticsearch"权威指南"在talking about dynamic mappings时说:

  

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

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

限制动态映射的选项:

<强> 1。在全球范围内

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

index.mapper.dynamic: false

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

$ 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

因此,对于任何级别的对象,root或嵌套此错误都会显示出来。 请注意,此设置的值为true / false而非strict(将被忽略为无效值)。

<强> 2。每个索引设置

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

例如,在创建索引时:

$ curl -XPUT localhost:9200/test -d '{
      "index.mapper.dynamic": false}
  }'
  {"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

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

第3。默认值为一个索引中的类型映射

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

创建索引时:

$ curl -XPUT localhost:9200/test -d '{
    "mappings": {
        "_default_": {
           "dynamic": "strict"
        }
    } 
}'
  {"acknowledged":true}

尝试添加新的未映射字段时会给您一个小错误:

$ 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}

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

$ curl -XPUT localhost:9200/test -d '{
    "mappings": {
       "_default_": {
          "dynamic": "strict"
       },
       "test": {
           "properties": {
               "foo": { "type": "string" },
               "bar": { 
                      "type": "nested",
                      "properties": {
                         "bell": { "type": "string" }
                      }
               }
           }
       }
     }
   }'

尝试不同的尝试时,结果为:

$ 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}

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

<强> 4。在索引映射对象中

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

$ curl -XPUT localhost:9200/test -d '{
  "mappings": {
    "test": {
      "dynamic": "strict",
      "properties": {
        "foo": {
          "type": "string"
        },
        "bar": {
          "type": "nested",
          "properties": {
            "bell": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}'

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

$ 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}

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

$ curl -XPUT localhost:9200/test -d '{
  "mappings": {
    "test": {
      "dynamic": "strict",
      "properties": {
        "foo": {
          "type": "string"
        },
        "bar": {
          "type": "nested",
          "dynamic": true,
          "properties": {
            "bell": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}'

结果:

$ 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}

但仍然无法在最高级别允许动态新字段:

$ 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}

摘要

最快的答案是,您可以禁用动态映射的所有方式向下传播到所有嵌套级别。你会发现旧的bug报告,旧的论坛消息和其他说明或暗示相反的例子但是Elasticsearch 2.4.0(我用于这个测试)上面的说法都是正确的。