3 Nesting HstQuery Filters
So far, we have seen how to bootstrap a HstQuery, and how to apply a Filter to it. At HstQuery Filter, it is also mentioned that, when adding constraints to a filter, all constraints are AND-ed.
Next to that, it is also possible to have OR-ed constraints. This can be done by OR-ing entire (sub)filters. A filter can be OR-ed or AND-ed with another filter. For example:
OR-ing two filters:
// the main filter
Filter filter = hstQuery.createFilter();
// some constraint on the main filter
filter.addContains(".", query);
// create subFilter 1 with some constraint
Filter subFilter1 = hstQuery.createFilter();
subFilter1.addEqualTo("hippostdpubwf:lastModifiedBy", "admin");
// create subFilter 2 with some constraint
Filter subFilter2 = hstQuery.createFilter();
subFilter2.addEqualTo("hippostdpubwf:createdBy", "admin");
// add subFilter1 and subFilter 2 as OR-ed filters
filter.addOrFilter(subFilter1);
filter.addOrFilter(subFilter2);
// alternative way to add subFilter in one statement
// filter.addOrFilter(subFilter1).addOrFilter(subFilter2);
// set the main filter on the request
hstQuery.setFilter(filter);
The code snippet above creates a query that returns only documents that:
-
contain ' query' AND
-
have a hippostdpubwf:lastModifiedBy = 'admin' OR hippostdpubwf:createdBy = 'admin' property.
To change above code snippet to apply AND logic, use filter.addAndFilter() instead:
// add subFilter1 and subFilter 2 as AND-ed filters filter.addAndFilter(subFilter1); filter.addAndFilter(subFilter2);
With this code, only documents that have hippostdpubwf:lastModifiedBy = 'admin' AND hippostdpubwf:createdBy = 'admin' will be returned.
There is an important thing to keep in mind when adding subfilters to a filter: To a single filter, you must only add OR-ed or only add AND-ed subfilters. The rationale behind this, is that we do not use brackets or precedence for child filters. Also, a more technical reason, Filter in the end in the repository are translated to Lucene BooleanQuery's, which do not have the notion of AND or OR, but only of MUST, MUST_NOT and SHOULD. For you, it is enough to remember:
To a single filter only add OR-ed or only add AND-ed subfilters
Therefore, the following code snippet is not correct, because AND-ing and OR-ing subfilters must not be combined in one filter:
// Wrong: Not allowed AND-ing and OR-ing filter.addAndFilter(subFilter1); filter.addOrFilter(subFilter2);
It is, however, correct if a filter has its nested subfilters OR-ed, while it is itself AND-ed with another filter, like in the example below:
// add an AND subFilter1 to the mainFilter mainFilter.addAndFilter(subFilter1); // add two OR filters to subFilter2 subFilter2.addOrFilter(subsub1); subFilter2.addOrFilter(subsub2); // add an AND subFilter2 to the mainFilter mainFilter.addAndFilter(subFilter2);
The above snippet creates a query where subFilter1 AND subFilter2 constraints must be met. For subFilter2, subsub1 OR subsub2 must be met.