<commit_before>[[nested]]
=== Nested datatype

The `nested` type is a specialised version of the <<object,`object`>> datatype
that allows arrays of objects to be indexed and queried independently of each
other.

==== How arrays of objects are flattened

Arrays of inner <<object,`object` fields>> do not work the way you may expect.
Lucene has no concept of inner objects, so Elasticsearch flattens object
hierarchies into a simple list of field names and values. For instance, the
following document:

[source,js]
--------------------------------------------------
PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [ <1>
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
--------------------------------------------------
// AUTOSENSE
<1> The `user` field is dynamically added as a field of type `object`.

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

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

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,js]
--------------------------------------------------
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}
--------------------------------------------------
// AUTOSENSE

==== 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, you should use the `nested` datatype instead of the
<<object,`object`>> datatype.  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,js]
--------------------------------------------------
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "user": {
          "type": "nested" <1>
        }
      }
    }
  }
}

PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

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

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

    }<commit_msg>Fixed nested query in documentation (#18608)<commit_after>[[nested]]
=== Nested datatype

The `nested` type is a specialised version of the <<object,`object`>> datatype
that allows arrays of objects to be indexed and queried independently of each
other.

==== How arrays of objects are flattened

Arrays of inner <<object,`object` fields>> do not work the way you may expect.
Lucene has no concept of inner objects, so Elasticsearch flattens object
hierarchies into a simple list of field names and values. For instance, the
following document:

[source,js]
--------------------------------------------------
PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [ <1>
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
--------------------------------------------------
// AUTOSENSE
<1> The `user` field is dynamically added as a field of type `object`.

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

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

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,js]
--------------------------------------------------
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}
--------------------------------------------------
// AUTOSENSE

==== 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, you should use the `nested` datatype instead of the
<<object,`object`>> datatype.  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,js]
--------------------------------------------------
PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "user": {
          "type": "nested" <1>
        }
      }
    }
  }
}

PUT my_index/my_type/1
{
  "group" : "fans",
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

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

GET my_index/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "must": [
            { "match": { "user.first": "Alice" }},
            { "match": { "user.last":  "White" }} <3>
          ]
        }
      },
      "inner_hits": { <4>
        "highlight": {
          "fields": {
            "user.first": {}
          }
        }
      }
    }
{'fraction_non_alphanumeric': 0.2447037150752226, 'fraction_numerical': 0.003223825606386245, 'mean_word_length': 1.6164658634538152, 'pattern_counts': {'":': 72, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4659576', 'n_tokens_mistral': 2011, 'n_tokens_neox': 1973, 'n_words': 591}