title: How to get an Elasticsearch aggregation with multiple fields
body: <p>I'm attempting to find related tags to the one currently being viewed. Every document in our index is tagged. Each tag is formed of two parts - an ID and text name:</p>
  
  <pre><code>{
      ...
      meta: {
          ...
          tags: [
              {
                  id: 123,
                  name: 'Biscuits'
              },
              {
                  id: 456,
                  name: 'Cakes'
              },
              {
                  id: 789,
                  name: 'Breads'
              }
          ]
      }
  }
  </code></pre>
  
  <p>To fetch the related tags I am simply querying the documents and getting an aggregate of their tags:</p>
  
  <pre><code>{
      "query": {
          "bool": {
              "must": [
                  {
                      "match": {
                          "item.meta.tags.id": "123"
                      }
                  },
                  {
                      ...
                  }
              ]
          }
      },
      "aggs": {
          "baked_goods": {
              "terms": {
                  "field": "item.meta.tags.id",
                  "min_doc_count": 2
              }
          }
      }
  }
  </code></pre>
  
  <p>This works perfectly, I am getting the results I want. However, I require both the tag ID <em>and</em> name to do anything useful. I have explored how to accomplish this, the solutions seem to be: </p>
  
  <ol>
  <li>Combine the fields when indexing</li>
  <li>A script to munge together the fields</li>
  <li>A nested aggregation</li>
  </ol>
  
  <p>Option one and two are are not available to me so I have been going with 3 but it's not responding in an expected manner. Given the following query (still searching for documents also tagged with 'Biscuits'):</p>
  
  <pre><code>{
      ...
      "aggs": {
          "baked_goods": {
              "terms": {
                  "field": "item.meta.tags.id",
                  "min_doc_count": 2
              },
              "aggs": {
                  "name": {
                      "terms": {
                          "field": "item.meta.tags.name"
                      }
                  }
              }
          }
      }
  }
  </code></pre>
  
  <p>I will get this result:</p>
  
  <pre><code>{
      ...
      "aggregations": {
          "baked_goods": {
              "buckets": [
                  {
                      "key": "456",
                      "doc_count": 11,
                      "name": {
                          "buckets": [
                              {
                                  "key": "Biscuits",
                                  "doc_count": 11
                              },
                              {
                                  "key": "Cakes",
                                  "doc_count": 11
                              }
                          ]
                      }
                  }
              ]
          }
      }
  }
  </code></pre>
  
  <p>The nested aggregation includes both the search term <em>and</em> the tag I'm after (returned in alphabetical order).</p>
  
  <p>I have tried to mitigate this by adding an <code>exclude</code> to the nested aggregation but this slowed the query down far too much (around 100 times for 500000 docs). So far the fastest solution is to de-dupe the result manually.</p>
  
  <p>What is the best way to get an aggregation of tags with both the tag ID and tag name in the response?</p>
  
  <p>Thanks for making it this far!</p>