如何用Java在Elasticsearch中按ID过滤嵌套列表条目
问题描述
我有一组包含NestedRecord集合的Record对象,需要通过指定的nestedId集合,过滤掉nestedRecords中不符合条件的条目,仅保留nestedId在目标集合内的NestedRecord。但我自己写的查询代码总是把所有内容都过滤掉,求修正。
实体类定义
public class Record { String id; Set<NestedRecord> nestedRecords; } public class NestedRecord { String nestedId; int count; }
目标过滤集合示例
Set<String> nestedIds = new HashSet<String>() {{ add("a"); add("b"); }};
出错的查询代码
TermsQueryBuilder recordExists = QueryBuilders.termsQuery("NESTED_RECORDS.NESTED_ID", Lists.newArrayList(nestedIds).toString()); NestedQueryBuilder nestedRecords = QueryBuilders.nestedQuery("NESTED_RECORDS", recordExists, ScoreMode.Total); BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(nestedRecords); query.filter(boolQuery);
问题分析与修正方案
错误原因
你把List转成String传给termsQuery了,Lists.newArrayList(nestedIds).toString()会生成类似"[a,b]"的字符串,ES会将这个字符串作为单个匹配值去查找NESTED_RECORDS.NESTED_ID,自然找不到任何匹配项,导致所有内容被过滤。
修正后的查询代码
1. 筛选包含符合条件NestedRecord的Record
如果只是要筛选出存在符合条件NestedRecord的Record,修正termsQuery的参数即可:
// 直接传入集合,无需转成String TermsQueryBuilder recordExists = QueryBuilders.termsQuery("NESTED_RECORDS.NESTED_ID", nestedIds); NestedQueryBuilder nestedRecords = QueryBuilders.nestedQuery("NESTED_RECORDS", recordExists, ScoreMode.Total); BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(nestedRecords); query.filter(boolQuery);
2. 同时返回Record中仅匹配的NestedRecord
如果需要返回的Record里只保留符合条件的NestedRecord(而非返回所有nestedRecords),需要添加inner_hits配置:
TermsQueryBuilder recordExists = QueryBuilders.termsQuery("NESTED_RECORDS.NESTED_ID", nestedIds); NestedQueryBuilder nestedRecords = QueryBuilders.nestedQuery("NESTED_RECORDS", recordExists, ScoreMode.Total) // 添加inner_hits,仅返回匹配的嵌套文档 .innerHit(new InnerHitBuilder().setName("matched_nested_records")); BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); boolQuery.must(nestedRecords); query.filter(boolQuery);
之后可通过查询结果的inner_hits获取每个Record对应的匹配NestedRecord列表。
内容的提问来源于stack exchange,提问作者midi
相关产品推荐
相关产品推荐

