ElasticSearch:嵌套查询的所有inner_hits合并及查询构建问题
解决Elasticsearch中合并嵌套查询inner_hits的问题
嘿,作为ES新手碰到这个inner_hits合并的需求太正常了!我来帮你一步步理清怎么搞定它,结合你的场景——在constant_score的filter里用bool must查询,想要把多个嵌套查询的inner_hits结果合并到一起,分两种常见情况给你方案:
情况1:同一个嵌套路径的多个查询条件
如果你的多个must条件都是针对同一个嵌套字段(比如都是查询comments嵌套字段),那最优雅的方式是把这些条件合并到同一个nested查询里,这样inner_hits会自动返回同时满足所有条件的嵌套文档,自然就是合并后的结果。
示例修改后的查询
假设你的原查询是分开的两个nested查询,修改后应该是这样:
{ "query": { "constant_score": { "filter": { "bool": { "must": [ { "nested": { "path": "comments", // 统一的嵌套路径 "query": { "bool": { "must": [ { "match": { "comments.text": "elasticsearch" } }, { "match": { "comments.author": "john" } } ] } }, "inner_hits": { "size": 100 // 可以根据需求调整返回的嵌套文档数量 } } } ] } } } } }
这样返回的inner_hits里,只会包含同时满足text含elasticsearch和author是john的comments文档,完美合并了条件对应的结果。
情况2:不同嵌套路径的查询条件
如果你的must条件是针对不同的嵌套字段(比如同时查询comments和tags两个嵌套路径),ES本身不会自动帮你合并不同嵌套查询的inner_hits,但我们可以通过统一inner_hits的名称,然后在应用层做合并。
示例修改后的查询
给每个嵌套查询的inner_hits设置相同的name参数:
{ "query": { "constant_score": { "filter": { "bool": { "must": [ { "nested": { "path": "comments", "query": { "match": { "comments.text": "elasticsearch" } }, "inner_hits": { "name": "all_matched_nested_docs", // 统一名称 "size": 100 } } }, { "nested": { "path": "tags", "query": { "term": { "tags.name": "tech" } }, "inner_hits": { "name": "all_matched_nested_docs", // 统一名称 "size": 100 } } } ] } } } } }
这时候返回结果里,hits.hits._inner_hits.all_matched_nested_docs.hits.hits会包含来自comments和tags的所有匹配嵌套文档,你只需要在应用代码里把这个数组直接用就行,相当于完成了合并。
额外注意点
- 记住
constant_score.filter里的bool must是要求父文档必须满足所有过滤条件,每个嵌套查询的作用是:父文档必须存在至少一个嵌套文档满足该嵌套查询才会被返回。 - 如果是同一个嵌套路径的多个条件,千万别分开写多个nested查询,否则会返回多个独立的inner_hits,不仅不好合并,还可能导致父文档被重复匹配。
- inner_hits的
size参数默认是10,如果需要返回更多匹配的嵌套文档,记得手动调整这个值。
内容的提问来源于stack exchange,提问作者Ark
相关产品推荐
相关产品推荐

