我使用的是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"
放在根目录。
我是否必须指定"动态":"严格"到所有级别的嵌入对象?换句话说,如果我设置"动态":"严格"在根级别,它是否也适用于嵌入式对象?
文档不清楚。
答案 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(我用于这个测试)上面的说法都是正确的。