我尝试在我的项目中使用 spring-data-elasticsearch 。当我想查询一些数据时,我在
queryForList(CriteriaQuery query, Class<T> clazz)
中使用ElasticsearchTemplate
。
但我不断从下面的代码中得到
NullPointerException
:
List<QueryBuilder> negationFilters = buildNegationFilter(criteria.getField().getName(), criteria.getFilterCriteriaEntries().iterator());
仅当我想将
not()
与 and()
一起使用时,才会出现此异常。当我单独使用 not()
时,它可以工作。
这是我的一些代码:
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()
.and(new Criteria("symbol").is("1111"))
.and(new Criteria("code").is("22").not()));
List<xx> sampleEntities = elasticsearchTemplate.queryForList(criteriaQuery,xx.class);
我怀疑源代码可能有错误:
在
CriteriaFilterProcessor
课上,
ListIterator<Criteria> chainIterator = criteria.getCriteriaChain().listIterator();
while (chainIterator.hasNext()) {
QueryBuilder fb = null;
Criteria chainedCriteria = chainIterator.next();
if (chainedCriteria.isOr()) {
fb = QueryBuilders.boolQuery();
for(QueryBuilder f: createFilterFragmentForCriteria(chainedCriteria)){
((BoolQueryBuilder)fb).should(f);
}
fbList.add(fb);
} else if (chainedCriteria.isNegating()) {
List<QueryBuilder> negationFilters = buildNegationFilter(criteria.getField().getName(), criteria.getFilterCriteriaEntries().iterator());
if (!negationFilters.isEmpty()) {
fbList.addAll(negationFilters);
}
} else {
fbList.addAll(createFilterFragmentForCriteria(chainedCriteria));
}
}
在
else if (chainedCriteria.isNegating())
部分,为什么要使用criteria
来获取字段?我调试了一下,发现criteria
的字段是null
,而chainedCriteria
不是。请问这是源码的bug还是我使用的方式不对?
我用
解决了CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()
.and(new Criteria("symbol").is("1111"))
.and("code").is("22").not());
如此连线,仍然想知道为什么有问题的代码无法工作
在尝试按照弹性文档中的建议构建“不得存在”过滤器时,我遇到类似的问题:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query。 html#find-docs-null-values
我有一个方法
getElasticsearchCriteria
,它可以一个接一个地构建Criteria
对象。在这种情况下,它会返回 return new Criteria(fieldName).exists().not();
。我像这样链接所有这些对象:
criteria.and(Utils.getElasticsearchCriteria(fieldName, value));
。当所有必要的 Criteria
对象都被链接起来时,我构建查询:
CriteriaQuery criteriaQuery = new CriteriaQuery(criteria, pageable);
最后,当尝试在
CriteriaQuery
的 search
方法中使用此类 ElasticsearchOperations
时,我遇到了异常:
java.lang.NullPointerException: Cannot invoke "org.springframework.data.elasticsearch.core.query.Field.getName()" because the return value of "org.springframework.data.elasticsearch.core.query.Criteria.getField()" is null
老实说,在我对这个框架进行了所有“冒险”之后,我得出的结论是,使用它的最方便的方法就是只使用
NativeQuery
并忘记 CriteriaQuery
。我知道它看起来要复杂得多,但通常所有方法都反映了文档中真实的 Elastic 方法。它大大简化了查询创建的过程,因为 Elastic 本身的社区比 Spring data elasticsearch 框架的社区大得多。随着客户需求变得更加复杂,我最终将一半的方法从 CriteriaQuery
重构为 NativeQuery
。