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.