Search code examples
elasticsearchelasticsearch-aggregationelasticsearch-7

Nested aggregation: how to get properties of aggregated object


I have a "products" index with the nested field mapping. I perform a search query with nested aggregation and term aggregation by nested object's id. How to get "title" and "slug" properties from nested object in buckets?

PUT /products
{
  "mappings": {
    "properties": {
      "categories": { 
        "type": "nested",
        "properties": {
          "id": { "type": "long" },
          "title": { "type": "text" },
          "slug": { "type": "keyword" }
        }
      }
    }
  }
}

POST /products/_doc
{
  "name": "Acer Aspire 5 Slim Laptop", 
  "categories": [
    {
      "id": 1,
      "title": "Laptops",
      "slug": "/catalog/laptops"
    },
    {
      "id": 2,
      "title": "Ultrabooks",
      "slug": "/catalog/ultrabooks"
    }
  ]
}

GET /products/_search
{
  "query": {
    "match": { "name": "acer" }
  },
  "aggs": {
    "categories": {
      "nested": {
        "path": "categories"
      },
      "aggs": {
       "id": {"terms": {"field": "categories.id"}}
      }
    }
  }
}

Solution

  • That's a great start!! All you need is to add a top_hits sub-aggregation like this:

    GET /products/_search
    {
      "query": {
        "match": {
          "name": "acer"
        }
      },
      "aggs": {
        "categories": {
          "nested": {
            "path": "categories"
          },
          "aggs": {
            "id": {
              "terms": {
                "field": "categories.id"
              },
              "aggs": {
                "hits": {
                  "top_hits": {
                    "size": 1,
                    "_source": ["categories.title", "categories.slug"]
                  }
                }
              }
            }
          }
        }
      }
    }