我正在互联网上积极地寻找解决方案,我知道可以完成,但我很沮丧,为什么它不能与Hibernate搜索一起工作。我要找的是类似于SQL子句where not in (1,2,3)
的东西我有两个实体A和b。
@Indexed
public class A
{
@Field
public String field1;
@FieldBridge(impl = LongBridge.class)
public Long field2;
@IndexEmbedded
public Set<B> names;
}
public class B {
@Field
public String field3;
@ContainedIn
public Set<A> names2;
}
我正在积极运行搜索使用querybuilder,看起来像这样:
queryBuilder.keyword()
.fuzzy()
.onFields("field1", "names.field3", "field2")
.matching(matching+"-field2:(1 2 3)")
.createQuery();
但matching
不读取这作为完整的Lucene匹配模式,我认为。它返回将field2
设置为1 2 3
的值,而不是将这些文档过滤掉。
EDIT1:我发现布尔查询生成器是有帮助的,我创建了调用not()
的查询,期望它过滤数据。底层的lucene查询是我所期望的,和我在第一种方法中写的一样,但是lucene仍然返回错误的值。另一方面,lucene索引查询的Luke工具使用这个表达式返回我所期望的。
EDIT2:我做错的是我使用了单个查询和连接值,而field2
的每个值应该由另一个布尔结携带。它现在工作得很好!
我做错了什么?我应该使用另一种机制吗?Hibernate搜索支持它吗?
.keyword()...matching( ... )
的参数不是接受特殊字符的查询。此方法期望传递纯文本。不能使用-
或:
。
如果所有这些内容都是由用户直接传递的,并且您确实需要一些接受操作符的内容,请查看simpleQueryString()
。
如果过滤器是由开发人员自己提供的,则只需使用bool
查询。
在你的例子中:
Query includedQuery = queryBuilder.keyword()
.fuzzy()
.onFields("field1", "names.field3", "field2")
.matching(matching)
.createQuery();
BooleanJunction<?> combinedQueryBuilder = querybuilder.bool();
combinedQueryBuilder.must(includedQuery);
for (String excluded : Arrays.asList("1", "2", "3")) {
combinedQueryBuilder.mustNot(queryBuilder.keyword()
.fuzzy()
.onField("field2")
.matching(excluded)
.createQuery());
}
Query combinedQuery = combinedQueryBuilder.createQuery();