diff --git a/_aggregations/bucket/nested.md b/_aggregations/bucket/nested.md index affda8e4375..591eaa3fded 100644 --- a/_aggregations/bucket/nested.md +++ b/_aggregations/bucket/nested.md @@ -9,77 +9,21 @@ redirect_from: # 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 +The `nested` aggregation lets you aggregate on fields inside a [nested]({{site.url}}{{site.baseurl}}/field-types/supported-field-types/nested/) object. The `nested` type is a specialized version of the `object` data type that indexes each element of an array of objects as a separate hidden document. This preserves the relationship between fields within the same array element so they can be queried and aggregated together. -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: +## Nested aggregation example -```json -PUT logs/_doc/0 -{ - "response": "200", - "pages": [ - { - "page": "landing", - "load_time": 200 - }, - { - "page": "blog", - "load_time": 500 - } - ] -} -``` -{% include copy-curl.html %} - -OpenSearch merges all sub-properties of the entity relations that looks something like this: +To aggregate over fields inside a nested array, specify the `path` to the nested field and define sub‑aggregations under it: ```json -{ - "logs": { - "pages": ["landing", "blog"], - "load_time": ["200", "500"] - } -} -``` - -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: - -```json -PUT logs -{ - "mappings": { - "properties": { - "pages": { - "type": "nested", - "properties": { - "page": { "type": "text" }, - "load_time": { "type": "double" } - } - } - } - } -} -``` -{% include copy-curl.html %} - -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: - - -```json -GET logs/_search +GET logs-nested/_search { "query": { "match": { "response": "200" } }, "aggs": { "pages": { - "nested": { - "path": "pages" - }, + "nested": { "path": "pages" }, "aggs": { "min_load_time": { "min": { "field": "pages.load_time" } } } @@ -89,17 +33,43 @@ GET logs/_search ``` {% include copy-curl.html %} -#### Example response +The returned hit contains the requested aggregation: ```json -... -"aggregations" : { - "pages" : { - "doc_count" : 2, - "min_load_time" : { - "value" : 200 +"hits": { + "total": { + "value": 1, + "relation": "eq" + }, + "max_score": 1, + "hits": [ + { + "_index": "logs-nested", + "_id": "0", + "_score": 1, + "_source": { + "response": "200", + "pages": [ + { + "page": "landing", + "load_time": 200 + }, + { + "page": "blog", + "load_time": 500 + } + ] + } + } + ] + }, + "aggregations": { + "pages": { + "doc_count": 2, + "min_load_time": { + "value": 200 + } } } - } -} ``` +