Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElasticSearch count nested fields

How do you count objects of a nested field (which is a nested objects list) which meet a certain condition in ElasticSearch?

EXAMPLE

Having Customer index, with type Customer which has a Services nested field with following structure:

public class Customer
{
    public int Id;
    public List<Service> Services;
}

public class Service
{
    public int Id;
    public DateTime Date;
    public decimal Rating;
}

How do I count all services which happened in June 2017 and got a rating higher than 5?

like image 384
skipper Avatar asked Sep 06 '25 03:09

skipper


1 Answers

Good question :) In order to get what you want you should define your mapping upfront and nested property mapping works well.

The nested type is a specialized version of the object datatype that allows arrays of objects to be indexed and queried independently of each other. https://www.elastic.co/guide/en/elasticsearch/reference/2.4/nested.html

Please find below full example :)

Mapping

PUT example_nested_test
{
  "mappings": {
    "nested": {
      "properties": {
        "Id": {
          "type": "long"
        },
        "Services": {
          "type": "nested",
          "properties": {
            "Id": {
              "type": "long"
            },
            "Date": {
              "type": "date"
            },
            "Rating": {
              "type": "long"
            }
          }
        }
      }
    }
  }
}

POST Data

POST example_nested_test/nested/100
    {
      "Id" : 1,
      "Services": [
        {
          "Id": 1,
          "Date" :"2017-05-10",
          "Rating" : 5
        },
         {
          "Id": 2,
          "Date" :"2013-05-10",
          "Rating" : 2
        },
        {
          "Id": 4,
          "Date" :"2017-05-10",
          "Rating" : 6
        }]
    }

Query

GET example_nested_test/_search
{
  "size":0, 
  "aggs": {
    "Services": {
      "nested": {
        "path": "Services"
      },
      "aggs": {
        "Rating": {
          "filter": {
            "bool": {
              "must": [
                {
                  "range": {
                    "Services.Date": {
                      "gt": "2017",
                      "format": "yyyy"
                    }
                  }
                },
                {
                  "range": {
                    "Services.Rating": {
                      "gt": "5"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

Result :

 "aggregations": {
    "Services": {
      "doc_count": 3,
      "Rating": {
        "doc_count": 1
      }
    }
  }
like image 69
natnael88 Avatar answered Sep 07 '25 21:09

natnael88