Search code examples
elasticsearchelastic-stack

Aggregations over all nested objects in a key in ElasticSearch


I have a document in the index 'submissions' which looks something like this,

{
  "took" : 18,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "submissions",
        "_type" : "_doc",
        "_id" : "90_169",
        "_score" : 1.0,
        "_source" : {
          "id" : "90_169",
          "locked" : false,
          "account_id" : 5,
          "campaign_id" : 90,
          "contact_id" : 1179,
          "submission_id" : 169,
          "answers" : [
            {
              "question_id" : 8451,
              "answer_bool" : true
            },
            {
              "question_id" : 8452,
              "answer_bool" : false
            },
            {
              "question_id" : 8453,
              "answer_bool" : true
            },
            {
              "question_id" : 8454,
              "answer_bool" : false
            }
          ]
        }
      }
    ]
  }
}

This is just one document.

I want to aggregate over all the questions to get a final bucket aggregations which shows number of true and false for each question_id.

Any insights on how to achieve this ?


Solution

  • You need to use nested aggregation along with terms and filter aggregation

    Adding a working example with index mapping, data, search query, and search result

    Index Mapping:

    {
      "mappings": {
        "properties": {
          "answers": {
            "type": "nested"
          }
        }
      }
    }
    

    Index data:

    {
      "id": "90_169",
      "locked": false,
      "account_id": 5,
      "campaign_id": 90,
      "contact_id": 1179,
      "submission_id": 169,
      "answers": [
        {
          "question_id": 8451,
          "answer_bool": true
        },
        {
          "question_id": 8452,
          "answer_bool": false
        },
        {
          "question_id": 8453,
          "answer_bool": true
        },
        {
          "question_id": 8454,
          "answer_bool": false
        }
      ]
    }
    {
      "id": "90_169",
      "locked": false,
      "account_id": 5,
      "campaign_id": 90,
      "contact_id": 1179,
      "submission_id": 169,
      "answers": [
        {
          "question_id": 8451,
          "answer_bool": true
        },
        {
          "question_id": 8452,
          "answer_bool": false
        },
        {
          "question_id": 8453,
          "answer_bool": true
        },
        {
          "question_id": 8454,
          "answer_bool": true
        }
      ]
    }
    {
      "id": "90_169",
      "locked": false,
      "account_id": 5,
      "campaign_id": 90,
      "contact_id": 1179,
      "submission_id": 169,
      "answers": [
        {
          "question_id": 8451,
          "answer_bool": true
        },
        {
          "question_id": 8452,
          "answer_bool": false
        },
        {
          "question_id": 8453,
          "answer_bool": true
        },
        {
          "question_id": 8454,
          "answer_bool": true
        }
      ]
    }
    

    Search Query:

    {
      "size": 0,
      "aggs": {
        "nested_Agg": {
          "nested": {
            "path": "answers"
          },
          "aggs": {
            "id": {
              "terms": {
                "field": "answers.question_id"
              },
              "aggs": {
                "true_count": {
                  "filter": {
                    "term": {
                      "answers.answer_bool": "true"
                    }
                  }
                },
                "false_count": {
                  "filter": {
                    "term": {
                      "answers.answer_bool": "false"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    

    Search Result:

    "aggregations": {
        "nested_Agg": {
          "doc_count": 12,
          "id": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": 8451,
                "doc_count": 3,
                "false_count": {
                  "doc_count": 0
                },
                "true_count": {
                  "doc_count": 3
                }
              },
              {
                "key": 8452,
                "doc_count": 3,
                "false_count": {
                  "doc_count": 3
                },
                "true_count": {
                  "doc_count": 0
                }
              },
              {
                "key": 8453,
                "doc_count": 3,
                "false_count": {
                  "doc_count": 0
                },
                "true_count": {
                  "doc_count": 3
                }
              },
              {
                "key": 8454,
                "doc_count": 3,
                "false_count": {
                  "doc_count": 1
                },
                "true_count": {
                  "doc_count": 2
                }
              }
            ]
          }
        }
      }