Elasticsearch对象数组映射异常:resource字段解析问题排查
问题
我正尝试创建一个包含对象数组的Elasticsearch索引,使用了如下mapping配置:
{ "mappings": { "date_detection": false, "properties": { "resource": { "type": "object", "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "uid": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "source": { "properties": { "serviceType": { "type": "text" }, "serviceId": { "type": "text" }, "state": { "type": "text" }, "type": { "type": "text" }, "connectorName": { "type": "text" }, "displayName": { "type": "text" } } }, "_key": { "type": "text" } } }, // 其他无关字段 } } }
插入了如下文档片段:
"resource": [ { "source": { "serviceType": "AWS", "serviceId": "...", "state": null, "type": "Source", "connectorName": "AWS", "displayName": null }, "name": "...", "id": "...", "_key": "...", "uid": "..." }, { "source": { "serviceType": "AWS", "serviceId": "..", "state": null, "type": "Source", "connectorName": "AWS", "displayName": null }, "name": "...", "id": "...", "_key": "...", "uid": "..." } ]
但发现resource字段未被正确解析,请问我遗漏了什么?
解决方案
问题出在你把resource的类型设置为object,但实际插入的是对象数组。Elasticsearch中,object类型处理数组时会扁平化存储,将数组里所有对象的同名字段合并在一起,导致无法区分数组中各个独立的对象,自然无法正确解析数组结构。
要正确存储和解析对象数组,你需要把resource的类型改成nested。nested类型会将数组中的每个对象作为独立的文档单元存储,保留对象的独立性,后续也支持对单个对象进行查询、聚合等操作。
修改后的resource字段mapping如下:
"resource": { "type": "nested", // 核心修改:从object改为nested "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "uid": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "id": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "source": { "properties": { "serviceType": { "type": "text" }, "serviceId": { "type": "text" }, "state": { "type": "text" }, "type": { "type": "text" }, "connectorName": { "type": "text" }, "displayName": { "type": "text" } } }, "_key": { "type": "text" } } }
注意:修改字段的核心类型需要重新创建索引,因为已创建的索引无法直接修改这类配置。你需要先删除原索引,再用修改后的mapping创建新索引,最后重新插入文档。
内容的提问来源于stack exchange,提问作者Idan
相关产品推荐
相关产品推荐

