4

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.

qwaz
  • 1,285
  • 4
  • 23
  • 47
  • 2
    You aggregated on `category.name`, you cannot have a different bucket key. My suggestion is to change the way you are indexing your documents, so that you can have a field that, also, contains the id. Something like `category.combined` and a possible value of "consumer electronics | 340". And the aggregation should be performed on `category.combined`. Before displaying the text to the user, you parse is and take out the name and the id. – Andrei Stefan May 14 '15 at 11:26
  • Wait, a have another idea. I'll post it as an answer in 5 min. – Andrei Stefan May 14 '15 at 11:33

2 Answers2

5

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
Andrei Stefan
  • 51,654
  • 6
  • 98
  • 89
1

You could add a sub aggregation:

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

This way each category.name bucket will contain a single bucket containing the id for that category.

hudsonb
  • 2,214
  • 19
  • 20