# Aggregating the specific nested documents only

**URL:** <https://discuss.elastic.co/t/aggregating-the-specific-nested-documents-only/133387>\
**Category:** Elasticsearch\
**Created:** [May 26, 2018, 10:16am UTC](https://discuss.elastic.co/t/aggregating-the-specific-nested-documents-only/133387 "2018-05-26T10:16:49Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![rakeshallampati](https://avatars.discourse-cdn.com/v4/letter/r/85f322/32.png) [@rakeshallampati](https://discuss.elastic.co/u/rakeshallampati)\
**Post date:** [May 26, 2018, 10:16am UTC](https://discuss.elastic.co/t/aggregating-the-specific-nested-documents-only/133387/1 "2018-05-26T10:16:49Z")

</div>

```
Hi,

I just want to aggregate the specific nested documents which satisfies the given query.

Let me explain it through an example,

i have two records in my index
first one ,
{
  "project": [
    {
      "subject": "maths",
      "marks": 47
    },
    {
      "subject": "computers",
      "marks": 22
    }
  ]
}

second one,
{
  "project": [
    {
      "subject": "maths",
      "marks": 65
    },
    {
      "subject": "networks",
      "marks": 72
    }
  ]
}

i just want to have an average of maths subject alone from the given documents.

so the query i tried is
{
  "size": 0,
  "aggs": {
    "avg_marks": {
      "avg": {
        "field": "project.marks"
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "project.subject:maths",
            "analyze_wildcard": true,
            "default_field": "*"
          }
        }
      ]
    }
  }
}
which was returning the result of aggreagating all the marks average which is not requireb by me,

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "avg_marks": {
      "value": 51.5
    }
  }
}

I just need an average of maths subject from the given documents, i expected result like below,

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "avg_marks": {
      "value": 56
    }
  }
}

Is there any possibility or any modification in my query would be helpful.

Thanks in Advance
```

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [May 29, 2018, 10:06am UTC](https://discuss.elastic.co/t/aggregating-the-specific-nested-documents-only/133387/2 "2018-05-29T10:06:00Z")

</div>

There are several ways of approaching this. Generally speaking, the most performant way would be to create a single document per project, rather than documents with multiple nested objects. Querying these flat "document per project" documents is going to be very fast.

However, if you need to use nested objects, make sure that you actually map those objects with [the nested datatype](https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html). Otherwise you will not be able to query and aggregate those nested objects independently.

In your case, you would create your index with a mapping like this (note the `project` field is mapped as type `nested`):

```auto
PUT my_index
{
  "mappings": {
    "_doc": {
      "properties": {
        "project": {
          "type": "nested",
          "properties": {
            "subject": {
              "type": "text"
            },
            "marks": {
              "type": "integer"
            }
          }
        }
      }
    }
  }
}

```

Now, you can index the documents like you have been doing:

```auto
PUT my_index/_doc/1
{
  "project": [
    {
      "subject": "maths",
      "marks": 47
    },
    {
      "subject": "computers",
      "marks": 22
    }
  ]
}

PUT my_index/_doc/2
{
  "project": [
    {
      "subject": "maths",
      "marks": 65
    },
    {
      "subject": "networks",
      "marks": 72
    }
  ]
}

```

Then, to get the aggregation results you want, you will need to use a [`nested` aggregation](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-nested-aggregation.html). You could move your query inside of this nested aggregation using a `filter` aggregation, to limit the aggregation scope to just those nested objects that match your query.

Your request would end up looking like this:

```auto
GET my_index/_search
{
  "size": 0,
  "aggs": {
    "nested_projects": {
      "nested": {
        "path": "project"
      },
      "aggs": {
        "filtered": {
          "filter": {
            "bool": {
              "must": [
                {
                  "query_string": {
                    "query": "project.subject:maths",
                    "analyze_wildcard": true,
                    "default_field": "*"
                  }
                }
              ]
            }
          },
          "aggs": {
            "avg_marks": {
              "avg": {
                "field": "project.marks"
              }
            }
          }
        }
      }
    }
  }
}

```

By the way, the `bool` query with just a single `must` clause does not really add anything. You could simplify the request to this and get the same results:

```auto
GET my_index/_search
{
  "size": 0,
  "aggs": {
    "nested_projects": {
      "nested": {
        "path": "project"
      },
      "aggs": {
        "filtered": {
          "filter": {
            "query_string": {
              "query": "project.subject:maths",
              "analyze_wildcard": true,
              "default_field": "*"
            }
          },
          "aggs": {
            "avg_marks": {
              "avg": {
                "field": "project.marks"
              }
            }
          }
        }
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [June 26, 2018, 10:06am UTC](https://discuss.elastic.co/t/aggregating-the-specific-nested-documents-only/133387/3 "2018-06-26T10:06:09Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
