子对象
编辑subobjects
编辑当索引文档或更新映射时,Elasticsearch 接受名称中包含点的字段,这些字段会扩展为其相应的对象结构。 例如,字段 metrics.time.max
被映射为一个 max
叶子字段,其父对象为 time
,而 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