Elasticsearch 6.0嵌套对象精准匹配查询问题求助
解决Elasticsearch嵌套数组对象的精准匹配问题
这坑我踩过!你现在遇到的核心问题是跨数组元素的匹配——当前的bool must查询会分别命中relationships数组里的不同对象,而不是要求同一个子对象同时满足所有三个条件。
举个例子,第二个返回结果里:
relationships.first_name:james匹配的是「Father: James Hickey」这个对象relationships.last_name:smith和relation:spouse匹配的是「Spouse: Richard Smith」这个对象
三个条件分散在不同子对象上,所以这条数据被错误地返回了。
解决方案:使用Nested查询
Elasticsearch默认会把数组中的对象扁平化存储,要实现同一个嵌套对象的多条件匹配,必须把relationships字段设置为nested类型,再用nested查询包裹条件。
步骤1:修改字段映射(若未设置Nested类型)
首先确认你的relationships字段是不是nested类型,如果不是,需要更新索引映射(ES 6.0仍支持类型,记得替换成你的索引名和类型名):
PUT /your_index/_mapping/your_document_type { "properties": { "relationships": { "type": "nested", "properties": { "first_name": {"type": "text"}, "last_name": {"type": "text"}, "relation": {"type": "text"} } } } }
注意:修改映射后需要重新索引所有数据,旧数据不会自动适配新的嵌套类型。
步骤2:编写Nested查询
用nested查询包裹所有条件,强制要求它们命中同一个子对象:
{ "query": { "bool": { "must": [ { "nested": { "path": "relationships", "query": { "bool": { "must": [ {"match": {"relationships.relation": "spouse"}}, {"match": {"relationships.first_name": "james"}}, {"match": {"relationships.last_name": "smith"}} ] } } } } ] } } }
这样查询只会返回那些存在至少一个relationships子对象同时满足relation=spouse、first_name包含james、last_name包含smith的文档,也就是你想要的第一个结果。
可选:更精准的匹配
如果需要完全精准匹配(比如first_name必须是「James S.」而不是包含james),可以用term查询配合keyword子字段(前提是你的映射里定义了keyword字段):
{ "query": { "bool": { "must": [ { "nested": { "path": "relationships", "query": { "bool": { "must": [ {"term": {"relationships.relation.keyword": "Spouse"}}, {"term": {"relationships.first_name.keyword": "James S."}}, {"term": {"relationships.last_name.keyword": "Smith"}} ] } } } } ] } } }
内容的提问来源于stack exchange,提问作者Sushil
相关产品推荐
相关产品推荐

