Multi-select facting in Java

Apache Solr

What is multi-select facting?

Multi-select faceting means that users can see and select multiple facet items (facet values) for particular facets. Thanks to Solr’s filter tagging and excluding features to support this type of faceting.

Online PC shop example

For example, we have 2 facets: memory, and brand. We want to support multi-select faceting because while searching, users may want to choose a range of memory size e.g. 4GB-8GB and a list of interested brands, e.g. Lenovo and HP.

From the initial search of keyword “Home desktop PC”, the result looks like:

1
2
3
4
5
------memory------ ------brand------
[ ] 2GB (30) [ ] Acer (13)
[ ] 4GB (50) [ ] HP (20)
[ ] 8GB (25) [ ] Lenovo (33)
[ ] 16GB (10) [ ] Toshiba (20)

Then user may want to narrow down the search results by selecting 4GB and 8GB in memory facet, also HP and Lenovo in the brand facet.

Ideally, after selecting 4GB and 8GB, users expect to see:

1
2
3
4
5
------memory------ ------brand------
[ ] 2GB (30) [ ] Acer (5)
[x] 4GB (50) [ ] HP (10)
[x] 8GB (25) [ ] Lenovo (13)
[ ] 16GB (10) [ ] Toshiba (10)

You may notice that the numbers after each brand facet item is also changed. That is just because the search results have been narrowed down after first select of “4GB” and “8GB” in memory facet.

Solr query to support multi-select faceting

According to solr’s documentation, tagging and excluding filters can be used to perform the multi-select faceting.

The solr query is:

1
q=Home%20desktop%20PC&facet=on&facet.field={!ex=tagmem}&fq={!tag=tagmem} memory:%28%224GB%208GB%22%29&facet.field={!ex=tagbrand}&fq={!tag=tagbrand}brand:%28%22Lenobo%20HP%22%29

Human readable version (should not send it to Solr in your application):

1
q=Home desktop PC&facet=on&facet.field={!ex=tagmem}&fq={!tag=tagmem}memory:("4GB" "8GB")&facet.field={!ex=tagbrand}&fq={!tag=tagbrand}brand:("Lenobo" "HP")

Solrj implementation

For facet:

1
2
3
4
5
SolrQuery query = new SolrQuery();
......
query.addFacetField("{!ex=tagmem}memory";
......
query.addFacetField("{!ex=tagbrand}brand";

For facet items:

1
query.addFilterQuery("{!tag=tagbrand}brand:"+YOUR_BRAND_FACET_VALUES_FROM_FRONTEND)
Share