I am actively searching through the Internet for solution to something that I know can be accomplished but I am frustrated why does it not work with Hibernate Search. What I am looking for is something similar to SQL clause where not in (1,2,3)
I have two entities, A and 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;
}
I am positively running search using querybuilder which looks like this:
queryBuilder.keyword()
.fuzzy()
.onFields("field1", "names.field3", "field2")
.matching(matching+"-field2:(1 2 3)")
.createQuery();
But matching
does not read this as full Lucene matching pattern I think. It returns values that have field2
set to 1 2 3
instead of filtering those documents out.
EDIT1:
I have found boolean query builder to be helpfull, I have created query with call to not()
expecting it to filter the data. The underlying lucene query is what I expected, the same as I wrote in the first approach, but the lucene still returns wrong values. On the other hand Luke tool for lucene indexes queries with this expression returns what I am expecting.
EDIT2:
What I was doing wrong is that I used single query and concatinated values, while each value of the field2
should have been carried by another boolean junction. It wokrs great now!
What do I do wrong? Should I use another mechanism? Is it even supported by Hibernate Search?
The argument to .keyword()...matching( ... )
is not a query that accepts special characters. This method expects to be passed plain text. You cannot use -
or :
in there.
If all this content is passed directly by users and you do need something that accepts operators, have a look at simpleQueryString()
.
If instead the filter is provided by yourself, the developer, just use the bool
query.
In your case:
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();