Nested datatype
editNested datatype
editThe nested
type is a specialised version of the object
datatype
that allows arrays of objects to be indexed in a way that they can be queried
independently of each other.
How arrays of objects are flattened
editArrays of inner 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:
PUT my_index/_doc/1 { "group" : "fans", "user" : [ { "first" : "John", "last" : "Smith" }, { "first" : "Alice", "last" : "White" } ] }
would be transformed internally into a document that looks more like this:
{ "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
:
GET my_index/_search { "query": { "bool": { "must": [ { "match": { "user.first": "Alice" }}, { "match": { "user.last": "Smith" }} ] } } }
Using nested
fields for arrays of objects
editIf 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
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 nested
query:
PUT my_index { "mappings": { "_doc": { "properties": { "user": { "type": "nested" } } } } } PUT my_index/_doc/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" }} ] } } } } } GET my_index/_search { "query": { "nested": { "path": "user", "query": { "bool": { "must": [ { "match": { "user.first": "Alice" }}, { "match": { "user.last": "White" }} ] } }, "inner_hits": { "highlight": { "fields": { "user.first": {} } } } } } }
The |
|
This query doesn’t match because |
|
This query matches because |
|
|
Nested documents can be:
-
queried with the
nested
query. -
analyzed with the
nested
andreverse_nested
aggregations. - sorted with nested sorting.
- retrieved and highlighted with nested inner hits.
Parameters for nested
fields
editThe following parameters are accepted by nested
fields:
Whether or not new |
|
The fields within the nested object, which can be of any
datatype, including |
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.
For instance, if a string field within a nested document has
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.
Limiting the number of nested
fields
editIndexing a document with 100 nested fields actually indexes 101 documents as each nested document is indexed as a separate document. To safeguard against ill-defined mappings the number of nested fields that can be defined per index has been limited to 50. See Settings to prevent mappings explosion.