Search code examples
elasticsearchelasticsearch-aggregation

Unique count of a document based on an array property of a nested property


Assuming it's the mapping of my index below, i want to create an elastic aggregation query to count the number of documents for each element of test array property

  • Mapping
"mappings": {
      "properties": {
        "code": {
          "type": "keyword"
        },
        "details": {
          "type": "nested",
          "properties": {
            "name": {
              "type": "text",
              "analyzer": "html_stripper"
            },            
            "elts": {
              "type": "integer"
            }
          }
        }
      }
    },
  • Exemple of a document
[
    {
        "code": "test",
        "details": [
            {"name": "test", "elts": [1,4]},
            {"name": "test", "elts": [1,4]}
        ]
    },
    {
        "code": "test2",
        "details": [
            {"name": "test2", "elts": [1,2,4]},
            {"name": "test2", "elts": [2,3]},

        ]
    }
]

I've tried this query

POST /my-index/_search

{
  "_source": false,  
  "aggs": {
    "inside_details": {
      "nested": {
        "path": "details"
      },
      "aggs": {
        "unique_count": {
          "terms": {
            "field": "details.elts",
            "order": {
              "_key": "asc"
            }
          }
        }
      }
    }
  }
}

But it's not working. Below the result

[
  {
    "key": "1",
    "doc_count": 3
  },
  {
    "key": "2",
    "doc_count": 2
  },
  {
    "key": "3",
    "doc_count": 1
  },
  {
    "key": "4",
    "doc_count": 3
  }
]

What i expect is a bucket like

[
  {
    "key": "1",
    "doc_count": 2
  },
  {
    "key": "2",
    "doc_count": 2
  },
  {
    "key": "3",
    "doc_count": 1
  },
  {
    "key": "4",
    "doc_count": 2
  }
]

Solution

  • You should nest the reverse_nested aggregation to count high-level documents

    GET /my-index/_search?filter_path=aggregations.inside_details.unique_count.buckets.key,aggregations.inside_details.unique_count.buckets.outside_details.doc_count
    {
        "aggs": {
            "inside_details": {
                "nested": {
                    "path": "details"
                },
                "aggs": {
                    "unique_count": {
                        "terms": {
                            "field": "details.elts",
                            "order": {
                                "_key": "asc"
                            }
                        },
                        "aggs": {
                            "outside_details": {
                                "reverse_nested": {},
                                "aggs": {
                                    "by_code": {
                                        "terms": {
                                            "field": "code"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

    Response

    {
        "aggregations" : {
            "inside_details" : {
                "unique_count" : {
                    "buckets" : [
                        {
                            "key" : 1,
                            "outside_details" : {
                                "doc_count" : 2
                            }
                        },
                        {
                            "key" : 2,
                            "outside_details" : {
                                "doc_count" : 1
                            }
                        },
                        {
                            "key" : 3,
                            "outside_details" : {
                                "doc_count" : 1
                            }
                        },
                        {
                            "key" : 4,
                            "outside_details" : {
                                "doc_count" : 2
                            }
                        }
                    ]
                }
            }
        }
    }
    

    I filter some sections of the response