Elasticsearch:如何编写查询存在子文档且无父文档的父文档的语句?
Elasticsearch 查询无父级且存在子文档的父文档
需求说明
需要筛选满足以下条件的父文档:
- 自身标记为父文档(
relation_type = parent) - 自身无父文档,且至少存在一个子文档
补全后的完整代码
Query query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.boolQuery() // 筛选自身为父文档的记录 .must(QueryBuilders.matchQuery("relation_type", "parent")) // 确保自身无父文档(覆盖字段不存在或为空的情况) .must(QueryBuilders.boolQuery() .should(QueryBuilders.boolQuery().mustNot(QueryBuilders.existsQuery("parent_id"))) .should(QueryBuilders.matchQuery("parent_id", "")) .minimumShouldMatch(1) ) // 查询存在任意子文档的父文档 .must(QueryBuilders.hasChildQuery( "instance", // 替换为你的子文档类型,ES7+ 统一用 "_doc" QueryBuilders.matchAllQuery(), ScoreMode.None )) ) .build();
代码解释
- 父文档标记筛选:通过
matchQuery匹配relation_type为parent的记录,锁定目标父文档范围。 - 无父文档校验:用布尔查询组合两种场景——
parent_id字段不存在,或parent_id为空字符串,minimumShouldMatch(1)保证满足任一条件即可。 - 存在子文档校验:使用
hasChildQuery指定子文档类型,内部用matchAllQuery匹配任意子文档(只要存在就符合条件);ScoreMode.None避免子文档评分干扰父文档排序。
旧写法失效原因
Elasticsearch 7.x 版本移除了多类型支持,同时 Spring Data Elasticsearch 对应 API 也做了调整,旧版嵌套调用hasChildQuery的方式不再适用,现在只需直接指定子文档类型和匹配条件即可。
内容的提问来源于stack exchange,提问作者Doyel Mishra
相关产品推荐
相关产品推荐

