子对象
编辑subobjects
编辑在索引文档或更新映射时,Elasticsearch 接受名称中包含点的字段,这些字段会被扩展到其对应的对象结构。例如,字段 metrics.time.max
被映射为一个 max
叶子字段,它有一个父 time
对象,属于其父 metrics
对象。
这种默认行为在大多数情况下是合理的,但在某些情况下会造成问题,例如字段 metrics.time
也保存了一个值,这在索引指标数据时很常见。如果一个文档同时为 metrics.time.max
和 metrics.time
保存了值,则会被拒绝,因为 time
需要同时作为叶子字段保存值,也需要作为对象保存 max
子字段。
subobjects
设置只能应用于顶级映射定义和 object
字段,它禁用对象保存更多子对象的能力,并使存储字段名称包含点并共享公共前缀的文档成为可能。从上面的例子来看,如果对象容器 metrics
的 subobjects
设置为 false
,它可以直接保存 time
和 time.max
的值,而无需任何中间对象,因为字段名称中的点将被保留。
resp = client.indices.create( index="my-index-000001", mappings={ "properties": { "metrics": { "type": "object", "subobjects": False, "properties": { "time": { "type": "long" }, "time.min": { "type": "long" }, "time.max": { "type": "long" } } } } }, ) print(resp) resp1 = client.index( index="my-index-000001", id="metric_1", document={ "metrics.time": 100, "metrics.time.min": 10, "metrics.time.max": 900 }, ) print(resp1) resp2 = client.index( index="my-index-000001", id="metric_2", document={ "metrics": { "time": 100, "time.min": 10, "time.max": 900 } }, ) print(resp2) resp3 = client.indices.get_mapping( index="my-index-000001", ) print(resp3)
response = client.indices.create( index: 'my-index-000001', body: { mappings: { properties: { metrics: { type: 'object', subobjects: false, properties: { time: { type: 'long' }, 'time.min' => { type: 'long' }, 'time.max' => { type: 'long' } } } } } } ) puts response response = client.index( index: 'my-index-000001', id: 'metric_1', body: { 'metrics.time' => 100, 'metrics.time.min' => 10, 'metrics.time.max' => 900 } ) puts response response = client.index( index: 'my-index-000001', id: 'metric_2', body: { metrics: { time: 100, 'time.min' => 10, 'time.max' => 900 } } ) puts response response = client.indices.get_mapping( index: 'my-index-000001' ) puts response
const response = await client.indices.create({ index: "my-index-000001", mappings: { properties: { metrics: { type: "object", subobjects: false, properties: { time: { type: "long", }, "time.min": { type: "long", }, "time.max": { type: "long", }, }, }, }, }, }); console.log(response); const response1 = await client.index({ index: "my-index-000001", id: "metric_1", document: { "metrics.time": 100, "metrics.time.min": 10, "metrics.time.max": 900, }, }); console.log(response1); const response2 = await client.index({ index: "my-index-000001", id: "metric_2", document: { metrics: { time: 100, "time.min": 10, "time.max": 900, }, }, }); console.log(response2); const response3 = await client.indices.getMapping({ index: "my-index-000001", }); console.log(response3);
PUT my-index-000001 { "mappings": { "properties": { "metrics": { "type": "object", "subobjects": false, "properties": { "time": { "type": "long" }, "time.min": { "type": "long" }, "time.max": { "type": "long" } } } } } } PUT my-index-000001/_doc/metric_1 { "metrics.time" : 100, "metrics.time.min" : 10, "metrics.time.max" : 900 } PUT my-index-000001/_doc/metric_2 { "metrics" : { "time" : 100, "time.min" : 10, "time.max" : 900 } } GET my-index-000001/_mapping
{ "my-index-000001" : { "mappings" : { "properties" : { "metrics" : { "subobjects" : false, "properties" : { "time" : { "type" : "long" }, "time.min" : { "type" : "long" }, "time.max" : { "type" : "long" } } } } } } }
也可以将整个映射配置为不支持子对象,在这种情况下,文档只能包含叶子子字段。
resp = client.indices.create( index="my-index-000001", mappings={ "subobjects": False }, ) print(resp) resp1 = client.index( index="my-index-000001", id="metric_1", document={ "time": "100ms", "time.min": "10ms", "time.max": "900ms" }, ) print(resp1)
response = client.indices.create( index: 'my-index-000001', body: { mappings: { subobjects: false } } ) puts response response = client.index( index: 'my-index-000001', id: 'metric_1', body: { time: '100ms', 'time.min' => '10ms', 'time.max' => '900ms' } ) puts response
const response = await client.indices.create({ index: "my-index-000001", mappings: { subobjects: false, }, }); console.log(response); const response1 = await client.index({ index: "my-index-000001", id: "metric_1", document: { time: "100ms", "time.min": "10ms", "time.max": "900ms", }, }); console.log(response1);
PUT my-index-000001 { "mappings": { "subobjects": false } } PUT my-index-000001/_doc/metric_1 { "time" : "100ms", "time.min" : "10ms", "time.max" : "900ms" }
现有字段和顶级映射定义的 subobjects
设置不能更新。
自动扁平化对象映射
编辑通常建议使用带点的字段名来定义配置了 subobjects: false
的对象的属性(如第一个示例所示)。但是,也可以在映射中将这些属性定义为子对象。在这种情况下,映射将在存储之前自动扁平化。这使得更容易重用现有映射,而无需重写它们。
请注意,当在配置为 subobjects: false
的对象下定义的对象映射上设置某些 映射参数 时,自动扁平化将不起作用。
enabled
映射参数不能为false
。dynamic
映射参数不能与父级的隐式或显式值相矛盾。例如,当在映射的根目录中将dynamic
设置为false
时,将dynamic
设置为true
的对象映射器无法自动扁平化。subobjects
映射参数不能显式设置为true
。
resp = client.indices.create( index="my-index-000002", mappings={ "properties": { "metrics": { "subobjects": False, "properties": { "time": { "type": "object", "properties": { "min": { "type": "long" }, "max": { "type": "long" } } } } } } }, ) print(resp) resp1 = client.indices.get_mapping( index="my-index-000002", ) print(resp1)
response = client.indices.create( index: 'my-index-000002', body: { mappings: { properties: { metrics: { subobjects: false, properties: { time: { type: 'object', properties: { min: { type: 'long' }, max: { type: 'long' } } } } } } } } ) puts response response = client.indices.get_mapping( index: 'my-index-000002' ) puts response
const response = await client.indices.create({ index: "my-index-000002", mappings: { properties: { metrics: { subobjects: false, properties: { time: { type: "object", properties: { min: { type: "long", }, max: { type: "long", }, }, }, }, }, }, }, }); console.log(response); const response1 = await client.indices.getMapping({ index: "my-index-000002", }); console.log(response1);
PUT my-index-000002 { "mappings": { "properties": { "metrics": { "subobjects": false, "properties": { "time": { "type": "object", "properties": { "min": { "type": "long" }, "max": { "type": "long" } } } } } } } } GET my-index-000002/_mapping