Home > Software design >  Dynamic count of items on Elasticsearch
Dynamic count of items on Elasticsearch

Time:11-05

Say that I have these 3 documents on a given index:

{
  "product_title":"dog shampoo",
  "properties":[
    {
      "type":"dog",
      "category":"hygiene"
    },
    {
      "type":"dog",
      "category":"foo"
    }
  ]
}

second

{
  "product_title":"cat  food",
  "properties":[
    {
      "type":"cat",
      "category":"food"
    },
    {
      "type":"cat",
      "category":"foo"
    }
  ]
}

third

{
  "product_title":"dog toy",
  "properties":[
    {
      "type":"dog",
      "category":"toys"
    },
    {
      "type":"dog",
      "category":"foo"
    }
  ]
}

And I want to count/aggregate how many products I have with every property['type'].

I already tried this using aggregations:

"aggregations" : {
    "dog" : {
      "value" : 4
    },
    "cat" : {
      "value" : 2
    },
  }

But the properties['type'] changes all the time so this must be done dynamically.

CodePudding user response:

For your example, you will need to use a nested aggregations. Assume you will have the following mappings:

{
    "mappings": {
        "properties": {
            "product_title": {
                "type": "text"
            },
            "properties": {
                "type": "nested",
                "properties": {
                    "type": {
                        "type": "keyword"
                    },
                    "category": {
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

So you first need to use a nested aggregation, and then use a terms to get the buckets for your properties.type:

{
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "properties": {
            "nested": {
                "path": "properties"
            },
            "aggs": {
                "by_type": {
                    "terms": {
                        "field": "properties.type"
                    }
                }
            }
        }
    }
}

This is the result:

  "aggregations": {
    "properties": {
      "doc_count": 6,
      "by_type": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "dog",
            "doc_count": 4
          },
          {
            "key": "cat",
            "doc_count": 2
          }
        ]
      }
    }
  }
  • Related