Java使用Elasticsearch Query DSL构建多条件查询报错求助
我在Elasticsearch中存储了包含字符串类型字段projectNumber和字符串列表字段projects的文档,需要筛选出指定项目编号等于projectNumber字段值或该项目编号存在于projects列表中的所有文档。
现有使用Elasticsearch Query DSL的Java代码如下:
import co.elastic.clients.elasticsearch._types.query_dsl.*; BoolQuery.Builder mainQuery = QueryBuilders.bool(); // 现有逻辑,不可修改 BoolQuery.Builder subQuery = QueryBuilders.bool(); subQuery.should(QueryBuilders.wildcard().field("projectNumber").value('*' + projectNumber + '*').build()._toQuery()); subQuery.should(org.elasticsearch.index.query.QueryBuilders.termsQuery("projects", projectNumber).toQuery()); mainQuery.must(subQuery.build()._toQuery());
这段代码存在编译问题:调用termsQuery的toQuery()方法时,提示“Cannot access org.apache.lucene.search.Query”;若移除该方法,则出现“Cannot resolve method 'should(TermsQueryBuilder)'”错误。
请问该如何解决?另外是否可以通过TermsQuery.Builder termsQuery = QueryBuilders.terms();的方式声明terms查询?
编译错误修复
代码编译失败的核心原因是混用了新旧两套Elasticsearch Java客户端API:你导入了新版客户端的co.elastic.clients包,却调用了旧版High Level REST Client的org.elasticsearch.index.query.QueryBuilders方法,两者的API结构不兼容。
需要统一使用新版客户端的API构建terms查询,修改后的完整代码如下:
import co.elastic.clients.elasticsearch._types.query_dsl.*; BoolQuery.Builder mainQuery = QueryBuilders.bool(); // 现有逻辑,不可修改 BoolQuery.Builder subQuery = QueryBuilders.bool(); // 保留原有wildcard查询逻辑 subQuery.should(QueryBuilders.wildcard() .field("projectNumber") .value("*" + projectNumber + "*") .build() ._toQuery()); // 使用新版客户端API构建terms查询 subQuery.should(QueryBuilders.terms() .field("projects") .value(projectNumber) .build() ._toQuery()); mainQuery.must(subQuery.build()._toQuery());
关于TermsQuery.Builder的声明方式
完全支持通过TermsQuery.Builder termsQuery = QueryBuilders.terms();的方式分步构建terms查询,这种写法更适合需要灵活设置多个参数的场景,示例代码如下:
// 分步初始化并配置terms查询 TermsQuery.Builder termsQueryBuilder = QueryBuilders.terms(); termsQueryBuilder.field("projects"); termsQueryBuilder.value(projectNumber); // 若需要添加多个值,可多次调用value或传入集合 // termsQueryBuilder.values(Arrays.asList(projectNumber, "other-project")); // 将构建好的查询加入should条件 subQuery.should(termsQueryBuilder.build()._toQuery());
内容的提问来源于stack exchange,提问作者Sanal M

