Building a filter query from a facet

When faceting is used, it is usually used in the context of faceted navigation, in which a facet value becomes a navigation choice for the user to filter on. In Solr, that becomes an additional filter query in a subsequent search. The total matching documents of that search should be equal to the facet value count. In this section, we'll review how to build the filter queries. We won't show an example for facet query faceting because there's nothing to do—the facet query is a query and can be supplied directly as an fq parameter.

Note

To keep the filter queries easier to read, we won't show them URL encoded.

Field value filter queries

For the case of field value faceting, consider the first example in the chapter where r_official has a value Bootleg. Generating a filter query for this couldn't be simpler: fq=r_official:Bootleg. But what if the value contained a space or some other problematic character? You'd have to escape it using quotes or backslash escaping as explained in Chapter 5, Searching. This is a separate issue from URL encoding, which we're omitting here for clarity; this pertains to the query syntax. Another potential problem relates to the fact that the value, even if escaped, still might have to go through text analysis in the field type configuration, which could modify the value resulting in a failed match. This is a rare circumstance and it's impossible with the string field type, but nonetheless it's something to watch out for, particularly for tag-cloud-like use cases. A solution to both problems is to use the term query parser, in this manner, fq={!term f=r_official}Bootleg. Here, the value needs no escaping as it sidesteps text analysis.

Tip

Consider using the term query parser for all text field value faceting as it avoids escaping problems.

You might be wondering how to generate a filter query for the facet.missing facet, as there is no value to filter on. Chapter 5, Searching, covered a little-known trick to query for a field with no indexed data involving a range query. Here it is for r_official, without URL encoding:

fq=-r_official:[* TO *].

Facet range filter queries

Range faceting is the most complicated to generate filter queries for. Consider the first date range example. The first facet returned is as follows:

"2003-01-01T00:00:00Z",2

The gap is +1YEAR. The facet's quoted date value is the start of the range. The end of the range is the next facet date value. If there are no more, then the final range's end point depends on facet.range.hardend—if it is false, the default, then you add facet.range.gap. For numbers, you calculate this math yourself. For dates, you can conveniently concatenate the string like this, 2006-01-01T00:00:00Z+1YEAR. On the other hand, if there is a hard end, then the last range end point is simply facet.range.end.

At this point, you might think the filter query for the first range is fq=r_event_date_earliest:[2006-01-01T00:00:00Z TO 2007-01-01T00:00:00Z]. However, that is incorrect! You must now consider the implications of facet.range.include. If you set this parameter to both lower and upper, then the aforementioned filter query would be correct, but by default it's just lower (which is generally a good default that doesn't double count). If a date falls on precisely New Year's Eve of 2014, then we don't want to count that date. The solution is to use this range query, fq=r_event_date_earliest:[2006-01-01T00:00:00Z TO 2007-01-01T00:00:00Z}—note the curly bracket (exclusivity) at the end of the range query. Varying exclusivity and inclusivity in a range query like this is a new feature as of Solr 4.

Generating filter queries for the before and after ranges isn't too hard. Here is the filter query for the before range, which is exclusive of the facet.range.start point:

fq=r_event_date_earliest:{* TO 2006-01-01T00:00:00Z}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset