Elasticsearch has_child查询未返回全部父文档问题排查
遇到这种has_child查询返回结果远少于预期的情况,大概率是关联关系、索引状态或者查询设置的问题,我给你列几个常见排查方向,你可以一步步来:
检查子文档与父文档的关联完整性
可能部分customer_query子文档没有正确关联到有效的customer父文档,或者关联的父文档根本不存在。你可以先通过聚合查询统计所有子文档对应的父ID数量:curl -XGET "http://localhost:9200/fts_index/customer_query/_search" -d' { "size": 0, "aggs": { "unique_parent_ids": { "terms": { "field": "your_parent_id_field", # 替换成你实际存储父文档ID的字段名 "size": 1000 } } } }'如果聚合结果里的唯一父ID数量刚好是23,那就说明确实只有23个父文档有对应的子文档,这时候你需要检查剩下的子文档是不是没关联父ID,或者关联的父ID有误。
排查查询的默认限制或参数问题
Elasticsearch的has_child查询默认没有子文档数量限制,但有时候可能不小心加了min_children/max_children参数(虽然你用的是match_all,但还是确认下)。另外,默认的分页size是10,但你返回了23条,说明不是默认分页的问题,但可以显式设置一个足够大的size值试试,排除分页截断的可能:curl -XGET "http://localhost:9200/fts_index/customer/_search" -d' { "size": 1000, # 设置一个大于预期父文档数的值 "query": { "has_child" : { "type" : "customer_query", "query" : { "match_all": {} } } } }'验证父文档是否存在
随机选几个没有出现在结果里的子文档的父ID,直接查询父文档是否存在:curl -XGET "http://localhost:9200/fts_index/customer/PARENT_ID_TO_CHECK"如果返回404,说明这个父文档已经被删除或者从未被索引,自然不会出现在
has_child的查询结果里。检查父子文档的mapping配置
确认customer_query的mapping里是否正确设置了父文档关联,正确的配置应该类似这样:{ "customer_query": { "_parent": { "type": "customer" }, "properties": { // 你的其他字段配置 } } }如果
_parent的type设置错误,或者根本没有配置这个关联,has_child查询就无法正确匹配父文档。排查路由(Routing)问题
如果你的父文档和子文档使用了自定义路由策略,查询时可能需要指定路由参数才能获取完整结果。比如如果子文档是按父文档ID路由的,你可以尝试加上routing=all参数查询:curl -XGET "http://localhost:9200/fts_index/customer/_search?routing=all" -d' { "query": { "has_child" : { "type" : "customer_query", "query" : { "match_all": {} } } } }'
内容的提问来源于stack exchange,提问作者user2671774

