Search code examples
lucenefull-text-searchelasticsearchpivot-tablefaceted-search

hierarchical faceting with Elasticsearch


I'm using elasticsearch and need to implement facet search for hierarchical object as follow:

  • category 1 (10)
    • subcategory 1 (4)
    • subcategory 2 (6)
  • category 2 (X)
    • ...

So I need to get facets for two related objects. Documentation says that it's possible to get such kind of facets for numeric value, but I need it for strings http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-facets-terms-stats-facet.html

Here is another interesting topic, unfortunately it's old: http://elasticsearch-users.115913.n3.nabble.com/Pivot-facets-td2981519.html

Does it possible with elastic search? If so, how can I do that?


Solution

  • Currently, elasticsearch does not support hierarchical facetting out-of-the-box. But the upcoming 1.0 release features a new aggregations module, that can be used to get these kind of facets (which are more like pivot-facets rather than hierarchical facets). Version 1.0 is currently in beta, you can download the second beta and test out aggregatins by yourself. Your example might look like

    curl -XPOST 'localhost:9200/_search?pretty' -d '
    {
       "aggregations": {
          "main category": {
             "terms": {
                "field": "cat_1",
                "order": {"_term": "asc"}
             },
             "aggregations": {
                "sub category": {
                   "terms": {
                      "field": "cat_2",
                      "order": {"_term": "asc"}
                   }
                }
             }
          }
       }
    }'
    

    The idea is, to have a different field for each level of facetting and bucket your facets based on the terms of the first level (cat_1). These aggregations then would have sub-buckets, based on the terms of the second level (cat_2). The result may look like

    {
      "aggregations" : {
        "main category" : {
          "buckets" : [ {
            "key" : "category 1",
            "doc_count" : 10,
            "sub category" : {
              "buckets" : [ {
                "key" : "subcategory 1",
                "doc_count" : 4
              }, {
                "key" : "subcategory 2",
                "doc_count" : 6
              } ]
            }
          }, {
            "key" : "category 2",
            "doc_count" : 7,
            "sub category" : {
              "buckets" : [ {
                "key" : "subcategory 1",
                "doc_count" : 3
              }, {
                "key" : "subcategory 2",
                "doc_count" : 4
              } ]
            }
          } ]
        }
      }
    }