[[nested]]
=== Nested field type
++++
<titleabbrev>Nested</titleabbrev>
++++

The `nested` type is a specialised version of the <<object,`object`>> data type
that allows arrays of objects to be indexed in a way that they can be queried
independently of each other.

TIP: When ingesting key-value pairs with a large, arbitrary set of keys, you might consider modeling each key-value pair as its own nested document with `key` and `value` fields. Instead, consider using the <<flattened,flattened>> data type, which maps an entire object as a single field and allows for simple searches over its contents.
Nested documents and queries are typically expensive, so using the `flattened` data type for this use case is a better option.

[[nested-arrays-flattening-objects]]
==== How arrays of objects are flattened

Elasticsearch has no concept of inner objects. Therefore, it flattens object
hierarchies into a simple list of field names and values. For instance, consider the
following document:

[source,console]
--------------------------------------------------
PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [ <1>
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
--------------------------------------------------

<1> The `user` field is dynamically added as a field of type `object`.

The previous document would be transformed internally into a document that looks more like this:

[source,js]
--------------------------------------------------
{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}
--------------------------------------------------
// NOTCONSOLE

The `user.first` and `user.last` fields are flattened into multi-value fields,
and the association between `alice` and `white` is lost.  This document would
incorrectly match a query for `alice AND smith`:

[source,console]
--------------------------------------------------
GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}
--------------------------------------------------
// TEST[continued]

[[nested-fields-array-objects]]
==== Using `nested` fields for arrays of objects

If you need to index arrays of objects and to maintain the independence of
each object in the array, use the `nested` data type instead of the
<<object,`object`>> data type.

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 with the <<query-dsl-nested-query,`nested` query>>:

[source,console]
--------------------------------------------------
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" <1>
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "Smith" }} <2>
          ]
        }
      }
    }
  }
}

GET my-index-000001/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} <3>
          ]
        }
      },
      "inner_hits": { <4>
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
  }
}
--------------------------------------------------

<1> The `user` field is mapped as type `nested` instead of type `object`.
<2> This query doesn't match because `Alice` and `Smith` are not in the same nested object.
<3> This query matches because `Alice` and `White` are in the same nested object.
<4> `inner_hits` allow us to highlight the matching nested documents.


[[nested-accessing-documents]]
==== Interacting with `nested` documents
Nested documents can be:

* queried with the <<query-dsl-nested-query,`nested`>> query.
* analyzed with the <<search-aggregations-bucket-nested-aggregation,`nested`>>
  and <<search-aggregations-bucket-reverse-nested-aggregation, `reverse_nested`>>
  aggregations.
* sorted with <<nested-sorting,nested sorting>>.
* retrieved and highlighted with <<nested-inner-hits,nested inner hits>>.

[IMPORTANT]
=============================================

Because nested documents are indexed as separate documents, they can only be
accessed  within the scope of the `nested` query, the
`nested`/`reverse_nested` aggregations, or <<nested-inner-hits,nested inner hits>>.

For instance, if a string field within a nested document has
<<index-options,`index_options`>> set to `offsets` to allow use of the postings
during the highlighting, these offsets will not be available during the main highlighting
phase.  Instead, highlighting needs to be performed via
<<nested-inner-hits,nested inner hits>>. The same consideration applies when loading
fields during a search through <<docvalue-fields,
`docvalue_fields`>> or <<stored-fields, `stored_fields`>>.

=============================================

[[nested-params]]
==== Parameters for `nested` fields

The following parameters are accepted by `nested` fields:

<<dynamic,`dynamic`>>::
(Optional, string)
Whether or not new `properties` should be added dynamically to an existing
nested object.  Accepts `true` (default), `false` and `strict`.

<<properties,`properties`>>::
(Optional, object)
The fields within the nested object, which can be of any
<<mapping-types,data type>>, including `nested`. New properties
may be added to an existing nested object.

[[nested-include-in-parent-parm]]
`include_in_parent`::
(Optional, boolean)
If `true`, all fields in the nested object are also added to the parent document
as standard (flat) fields. Defaults to `false`.

[[nested-include-in-root-parm]]
`include_in_root`::
(Optional, boolean)
If `true`, all fields in the nested object are also added to the root
document as standard (flat) fields. Defaults to `false`.

[discrete]
=== Limits on `nested` mappings and objects

As described earlier, each nested object is indexed as a separate Lucene document.
Continuing with the previous example, if we indexed a single document containing 100 `user` objects,
then 101 Lucene documents would be created: one for the parent document, and one for each
nested object. Because of the expense associated with `nested` mappings, Elasticsearch puts
settings in place to guard against performance problems:

include::{es-repo-dir}/mapping.asciidoc[tag=nested-fields-limit]

In the previous example, the `user` mapping would count as only 1 towards this limit.

include::{es-repo-dir}/mapping.asciidoc[tag=nested-objects-limit]

To illustrate how this setting works, consider adding another `nested` type called `comments`
to the previous example mapping. For each document, the combined number of `user` and `comment`
objects it contains must be below the limit.

See <<mapping-limit-settings>> regarding additional settings for preventing mappings explosion.
