Search code examples
elasticsearchfaceted-search

elasticsearch - additional field in aggregation results


I have the following aggregation for Categories

{
    "aggs": {
        "category": {
            "terms": { "field": "category.name" }
        }
    }
}

// results
"category": {
    "buckets": [
        {
            "key": "computer & office",
            "doc_count": 365
        },
        {
            "key": "home & garden",
            "doc_count": 171
        },
        {
            "key": "consumer electronics",
            "doc_count": 49
        },
    ]
}

How can I pass additional field, like category.id to the category buckets, so I could query by category.id if the certain aggregation is clicked by a user. I'm not really clear how to query aggregations, if there's any direct way or you have to make a new query and pass bucket key to query filters.


Solution

  • Use a sub-aggregation on the category.id, you will do a bit more work when looking at the results, but I think it's better than changing the mapping:

    {
      "aggs": {
        "name": {
          "terms": {
            "field": "name"
          },
          "aggs": {
            "id": {
              "terms": {
                "field": "id"
              }
            }
          }
        }
      }
    }
    

    And the results will look like the following:

       "aggregations": {
          "name": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
                {
                   "key": "consumer electronics",
                   "doc_count": 2,
                   "id": {
                      "doc_count_error_upper_bound": 0,
                      "sum_other_doc_count": 0,
                      "buckets": [
                         {
                            "key": 2,
                            "doc_count": 2
                         }
                      ]
                   }
                },
                {
                   "key": "computer & office",
                   "doc_count": 1,
                   "id": {
                      "doc_count_error_upper_bound": 0,
                      "sum_other_doc_count": 0,
                      "buckets": [
                         {
                            "key": 5,
                            "doc_count": 1
                         }
                      ]
                   }
                },
                {
                   "key": "home & garden",
                   "doc_count": 1,
                   "id": {
                      "doc_count_error_upper_bound": 0,
                      "sum_other_doc_count": 0,
                      "buckets": [
                         {
                            "key": 1,
                            "doc_count": 1
                         }
                      ]
                   }
                },
                {
                   "key": "whatever",
                   "doc_count": 1,
                   "id": {
                      "doc_count_error_upper_bound": 0,
                      "sum_other_doc_count": 0,
                      "buckets": [
                         {
                            "key": 3,
                            "doc_count": 1
                         }
                      ]
                   }
                }
             ]
          }
       }
    

    You will still have the category name, but now you, also, have the id from the second aggregation as a sub-bucket in the root bucket:

                   "key": "consumer electronics",
                   ...
                   "id": {
                      ...
                      "buckets": [
                         {
                            "key": 2,
                            "doc_count": 2