Search code examples
solrfacetfaceted-search

Multiple facet.prefix on a single facet field


I'm creating a search app which intensively uses Solr (5.2.1) faceting functionality. One requirement is to limit the number of facets returned by prefix for a specified field.

The standard Solr query syntax works well for a single prefix value:

/select?q=*%3A*&rows=0&wt=json&indent=true&facet=true&facet.field=DocumentKind&f.DocumentKind.facet.prefix=faq

Output:

"facet_counts": {
    "facet_queries": {},
    "facet_fields": {
      "DocumentKind": {
        "faq": 1523
      }
      ...

Unfortunately this doesn't work when I must limit the facets on the field with more than one prefix:

/select?q=*%3A*&rows=0&wt=json&indent=true&facet=true&facet.field=DocumentKind&f.DocumentKind.facet.prefix=manual&f.DocumentKind.facet.prefix=faq

I expected it will return something like this:

"facet_counts": {
    "facet_queries": {},
    "facet_fields": {
      "DocumentKind": {
        "faq": 1523,
        "manual": 2366
      }
      ...

But it gives the same output as previous.

In the example above I match the entire facet value but in the real use case I really have to match the prefix. I showed this example for brevity.

I could filter this out in my app but the size of data returned unnecessarily by Solr is significant.


Solution

  • I had a similar problem in my application. The solution for that problem are facet local params. I.e. if I'm faceting data from Solr techproducts example to find out number of products available or not available inStock I need to run query like this:

    http://localhost:8983/solr/techproducts/select?q=*%3A*&wt=json&indent=true&facet=true&facet.field=inStock
    

    and I will get following result that includes all dictinct values from inStock field:

    ...
    "facet_counts":{
        "facet_queries":{},
        "facet_fields":{
          "inStock":[
            "true",17,
            "false",4]},
        "facet_dates":{},
    ...
    

    But in your case you want to distinguish facet results using multiple prefixes for field value. And here local params are very handy tool. Now, if I want to do facating based on specific value from inStock field like true or false and i need to use !key to label the results:

    http://localhost:8983/solr/techproducts/select?q=*:*&wt=json&indent=true&facet=true&facet.field={!key=inStock_True+facet.prefix=true}inStock
    
    ...
    "facet_counts":{
        "facet_queries":{},
        "facet_fields":{
          "inStock_True":[
            "true",17]},
        "facet_dates":{},
    ...
    

    So after querying your data using multiple facet local params prefixes:

    /select?q=*:*&rows=0&wt=json&indent=true&facet=true&facet.field={!key=DocumentKind_manual+facet.prefix=manual}DocumentKind&facet.field={!key=DocumentKind_faq+facet.prefix=faq}DocumentKind
    

    and you will see results like that:

    ...
        "facet_counts":{
            "facet_queries":{},
            "facet_fields":{
              "DocumentKind_faq":[
                "faq",1523],
              "DocumentKind_manual":[
                "manual",2366]},
    ...