Hibernate Search 5 BooleanJunction has a useful isEmpty() method to you can determine whether any clauses actually exist. This helps when building the Queries upstream b/c we won't include, or will alter our Query if a particular BooleanJunction is empty since it will not provide the results desired.
What is the equivalent for BooleanPredicateClausesStep in Hibernate Search 6? I don't see one, so is there another way to determine whether a BooleanPredicateClausesStep is empty or has no clauses contained within it?
Providing some example code to illustrate.
Hibernate Search 5.10.7.Final:
public Query buildProbableVendorNamesQuery(FullTextSession fts, QueryBuilder qb, Set<String> vendorNames) {
BooleanJunction namesBool = qb.bool();
vendorNames.forEach(name ->
addProbableVendorNameBool(fts, qb, namesBool, name)
);
return namesBool.isEmpty() ? null : namesBool.createQuery();
}
Hibernate Search 6.1.5.Final:
public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
BooleanPredicateClausesStep namesBool = pf.bool();
vendorNames.forEach(name ->
addProbableVendorNameBool(pf, namesBool, name)
);
//TODO: How can we know if namesBool is empty so we can return null?
return namesBool.toPredicate();
}
There are various reasons why namesBool could be empty, 1 being that the name itself ended up being a stop word or normalizing down to nothing. In that case we'd want to inform the caller upstream that the SearchPredicate is null so don't attempt to use it in a query.
CodePudding user response:
There is no equivalent in Hibernate Search 6 at the moment. I created HSEARCH-4618 to address that; if you want the feature soon, you can consider contributing, as this would be a relatively easy first contribution to Hibernate Search.
In the meantime, you can pass a List
to addProbableVendorNameBool
as a workaround. While not very pretty, it will work:
public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
List<SearchPredicate> clauses = new ArrayList();
vendorNames.forEach(name ->
addProbableVendorNameBool(pf, clauses, name)
);
if (clauses.isEmpty()) {
return null;
}
BooleanPredicateClausesStep namesBool = pf.bool();
clauses.forEach(namesBool::should);
return namesBool.toPredicate();
}
private void addProbableVendorNameBool(SearchPredicateFactory pf, List<SearchPredicate> clauses, String name) {
...
}
Or, if you can change addProbableVendorNameBool
so that it returns exactly exactly one predicate (e.g. by having it create its own boolean predicate if necessary) or null
:
public SearchPredicate buildProbableVendorNamesPredicate(SearchPredicateFactory pf, Set<String> vendorNames) {
List<SearchPredicate> clauses = vendorNames.stream()
.map(name -> buildProbableVendorSingleNamePredicate(pf, name))
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (clauses.isEmpty()) {
return null;
}
BooleanPredicateClausesStep namesBool = pf.bool();
clauses.forEach(namesBool::should);
return namesBool.toPredicate();
}
private SearchPredicate buildProbableVendorSingleNamePredicate(SearchPredicateFactory pf, String name) {
...
return <something or null>;
}