This version of the OpenSearch documentation is no longer maintained. For the latest version, see the current documentation. For information about OpenSearch version maintenance, see Release Schedule and Maintenance Policy.

Nested aggregations

The nested aggregation lets you aggregate on fields inside a nested object. The nested type is a specialized version of the object data type that allows arrays of objects to be indexed in a way that they can be queried independently of each other

With the object type, all the data is stored in the same document, so matches for a search can go across sub documents. For example, imagine a logs index with pages mapped as an object datatype:

  1. PUT logs/_doc/0
  2. {
  3. "response": "200",
  4. "pages": [
  5. {
  6. "page": "landing",
  7. "load_time": 200
  8. },
  9. {
  10. "page": "blog",
  11. "load_time": 500
  12. }
  13. ]
  14. }

copy

OpenSearch merges all sub-properties of the entity relations that looks something like this:

  1. {
  2. "logs": {
  3. "pages": ["landing", "blog"],
  4. "load_time": ["200", "500"]
  5. }
  6. }

So, if you wanted to search this index with pages=landing and load_time=500, this document matches the criteria even though the load_time value for landing is 200.

If you want to make sure such cross-object matches don’t happen, map the field as a nested type:

  1. PUT logs
  2. {
  3. "mappings": {
  4. "properties": {
  5. "pages": {
  6. "type": "nested",
  7. "properties": {
  8. "page": { "type": "text" },
  9. "load_time": { "type": "double" }
  10. }
  11. }
  12. }
  13. }
  14. }

copy

Nested documents allow you to index the same JSON document but will keep your pages in separate Lucene documents, making only searches like pages=landing and load_time=200 return the expected result. Internally, nested objects index each object in the array as a separate hidden document, meaning that each nested object can be queried independently of the others.

You have to specify a nested path relative to parent that contains the nested documents:

  1. GET logs/_search
  2. {
  3. "query": {
  4. "match": { "response": "200" }
  5. },
  6. "aggs": {
  7. "pages": {
  8. "nested": {
  9. "path": "pages"
  10. },
  11. "aggs": {
  12. "min_load_time": { "min": { "field": "pages.load_time" } }
  13. }
  14. }
  15. }
  16. }

copy

Example response

  1. ...
  2. "aggregations" : {
  3. "pages" : {
  4. "doc_count" : 2,
  5. "min_price" : {
  6. "value" : 200.0
  7. }
  8. }
  9. }
  10. }