This article covers a Bloomreach Experience Manager version 12. There's an updated version available that covers our most recent release.

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:

  1. contain ' queryAND

  2. 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.

It is supported to have subfilters added to a main filter, where the main filter does not have direct constraints (such as f.e. the filter.addContains()). Also, subfilters can again have nested subfilters; it is a composite structure.

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.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?