Search code examples
elasticsearchfaceted-searchfacet

Dynamic facets in elasticsearch. Nested facets?


I have Products, that has many Features. Schema looks something like this

[{
  name: "Test product 1",
  features: [
    ...
    {name: "color", value: "Blue"},
    {name: "size", value: "M"},
    ...
  ]
},{
  name: "Test product 2",
  features: [
    ...
    {name: "color", value: "Blue"},
    {name: "size", value: "XL"}
    ...
  ]
},{
  name: "Test product 3",
  features: [
    ...
    {name: "color", value: "White"},
    {name: "size", value: "XL"}
    ...
  ]
}]

I want to get facets for each distinct value of each feature. Something like this:

{
  color: {
    Blue: 2,
    White: 1
  },
  size: {
    M: 1,
    XL: 2
  }
}

How to design a proper index schema and how to query for this facets? Should I create two different arrays, one for feature names, and other with items of type "object"... And then make multiple queries, first for feature names and then for each nested facets?...

Sorry, i'm confused, and don't understand how to get this result with facets


Solution

  • Why are trying to use facet ?? Facets are deprecating, use aggregation ..

    Here is a way to do the search, using facet and aggregation.. 1. Create index and put mapping

    PUT x3
    POST x3/x2/_mapping
    {
        "x2":{
            "properties": {
                "features" :{
                    "type": "nested"
                }
            }
        }
    }
    POST x3/x2/1
    {
      "name" :"Test product 1",
      "features": [
        {"name": "color", "value": "Blue"},
        {"name": "size", "value": "M"}
      ]
    }
    
    POST x3/x2/2
    {
      "name": "Test product 2",
      "features": [
        {"name": "color", "value": "Blue"},
        {"name": "size", "value": "XL"}
      ]
    }
    

    Search using facet

    POST x3/x2/_search
    {
       "size": 0,
       "facets": {
          "sizeFacet": {
             "terms": {
                "field": "features.value",
                "size": 10000
             },
             "facet_filter": {
                "term": {
                   "features.name": "color"
                }
             },
             "nested": "features"
          },
          "colorFacet": {
             "terms": {
                "field": "features.value",
                "size": 10000
             },
             "facet_filter": {
                "term": {
                   "features.name": "size"
                }
             },
             "nested": "features"
          }
       }
    }
    

    Search using aggregation..

    POST x3/x2/_search
    {
       "size": 0,
       "aggs": {
          "features": {
             "nested": {
                "path": "features"
             },
             "aggs": {
                "names": {
                   "terms": {
                      "field": "features.name",
                      "size": 0
                   },
                   "aggs": {
                      "value": {
                         "terms": {
                            "field": "features.value",
                            "size": 0
                         }
                      }
                   }
                }
             }
          }
       }
    }