--- layout: default title: Nested parent: Joining queries nav_order: 5 --- # Nested query The `nested` query acts as a wrapper for other queries to search [nested]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/nested/) fields. The nested field objects are searched as though they were indexed as separate documents. If an object matches the search, the `nested` query returns the parent document at the root level. ## Example Before you can run a `nested` query, your index must contain a [nested]({{site.url}}{{site.baseurl}}/mappings/supported-field-types/nested/) field. To configure an example index containing nested fields, send the following request: ```json PUT /testindex { "mappings": { "properties": { "patient": { "type": "nested", "properties": { "name": { "type": "text" }, "age": { "type": "integer" } } } } } } ``` {% include copy-curl.html %} Next, index a document into the example index: ```json PUT /testindex/_doc/1 { "patient": { "name": "John Doe", "age": 56 } } ``` {% include copy-curl.html %} To search the nested `patient` field, wrap your query in a `nested` query and provide the `path` to the nested field: ```json GET /testindex/_search { "query": { "nested": { "path": "patient", "query": { "match": { "patient.name": "John" } } } } } ``` {% include copy-curl.html %} The query returns the matching document: ```json { "took": 3, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.13076457, "hits": [ { "_index": "testindex", "_id": "1", "_score": 0.13076457, "_source": { "patient": { "name": "John Doe", "age": 56 } } } ] } } ``` ## Retrieving inner hits To return inner hits that matched the query, provide the `inner_hits` parameter: ```json GET /testindex/_search { "query": { "nested": { "path": "patient", "query": { "match": { "patient.name": "John" } }, "inner_hits": {} } } } ``` {% include copy-curl.html %} The response contains the additional `inner_hits` field. The `_nested` field identifies the specific inner object from which the inner hit originated. It contains the nested hit and the offset relative to its position in the `_source`. Because of sorting and scoring, the position of the hit objects in `inner_hits` often differs from their original location in the nested object. By default, the `_source` of the hit objects within `inner_hits` is returned relative to the `_nested` field. In this example, the `_source` within `inner_hits` contains the `name` and `age` fields as opposed to the top-level `_source`, which contains the whole `patient` object: ```json { "took": 38, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.13076457, "hits": [ { "_index": "testindex", "_id": "1", "_score": 0.13076457, "_source": { "patient": { "name": "John Doe", "age": 56 } }, "inner_hits": { "patient": { "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.13076457, "hits": [ { "_index": "testindex", "_id": "1", "_nested": { "field": "patient", "offset": 0 }, "_score": 0.13076457, "_source": { "name": "John Doe", "age": 56 } } ] } } } } ] } } ``` You can disable returning `_source` by configuring the `_source` field in the mappings. For more information, see [Source]({{site.url}}{{site.baseurl}}/mappings/metadata-fields/source/). {: .tip} For more information about retrieving inner hits, see [Inner hits]({{site.url}}{{site.baseurl}}/search-plugins/searching-data/inner-hits/). ## Multi-level nested queries You can search documents that have nested objects inside other nested objects using multi-level nested queries. In this example, you'll query multiple layers of nested fields by specifying a nested query for each level of the hierarchy. First, create an index with multi-level nested fields: ```json PUT /patients { "mappings": { "properties": { "patient": { "type": "nested", "properties": { "name": { "type": "text" }, "contacts": { "type": "nested", "properties": { "name": { "type": "text" }, "relationship": { "type": "text" }, "phone": { "type": "keyword" } } } } } } } } ``` {% include copy-curl.html %} Next, index two documents into the example index: ```json PUT /patients/_doc/1 { "patient": { "name": "John Doe", "contacts": [ { "name": "Jane Doe", "relationship": "mother", "phone": "5551111" }, { "name": "Joe Doe", "relationship": "father", "phone": "5552222" } ] } } ``` {% include copy-curl.html %} ```json PUT /patients/_doc/2?refresh { "patient": { "name": "Mary Major", "contacts": [ { "name": "Jane Major", "relationship": "sister", "phone": "5553333" }, { "name": "Paula Major", "relationship": "mother", "phone": "5554444" } ] } } ``` {% include copy-curl.html %} To search the nested `patient` field, use a multi-level `nested` query. The following query searches for patients whose contact information includes a person named `Jane` with a relationship of `mother`: ```json GET /patients/_search { "query": { "nested": { "path": "patient", "query": { "nested": { "path": "patient.contacts", "query": { "bool": { "must": [ { "match": { "patient.contacts.relationship": "mother" } }, { "match": { "patient.contacts.name": "Jane" } } ] } } } } } } } ``` {% include copy-curl.html %} Both conditions in the inner `bool` query must match the same contact object. Document 2 has a contact named `Jane` and a contact whose relationship is `mother`, but they are different contacts, so only document 1 is returned. If `contacts` were mapped as an `object` field instead of `nested`, the contact values would be flattened into arrays, and the same conditions would match both documents. The query returns the patient who has a contact entry matching these details: ```json { "took": 9, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 1, "relation": "eq" }, "max_score": 0.63013375, "hits": [ { "_index": "patients", "_id": "1", "_score": 0.63013375, "_source": { "patient": { "name": "John Doe", "contacts": [ { "name": "Jane Doe", "relationship": "mother", "phone": "5551111" }, { "name": "Joe Doe", "relationship": "father", "phone": "5552222" } ] } } } ] } } ``` ## Parameters The following table lists all top-level parameters supported by `nested` queries. | Parameter | Required/Optional | Description | |:---|:---|:---| | `path` | Required | Specifies the path to the nested object that you want to search. | | `query` | Required | The query to run on the nested objects within the specified `path`. If a nested object matches the query, the root parent document is returned. You can search nested fields using dot notation, such as `nested_object.subfield`. Multi-level nesting is supported and automatically detected. Thus, an inner `nested` query within another nested query automatically matches the correct nesting level, instead of the root. | | `ignore_unmapped` | Optional | Indicates whether to ignore unmapped `path` fields and not return documents instead of throwing an error. You can provide this parameter when querying multiple indexes, some of which may not contain the `path` field. Default is `false`. | | `score_mode` | Optional | Defines how scores of matching inner documents influence the parent document's score. Valid values are:
- `avg`: Uses the average relevance score of all matching inner documents.
- `max`: Assigns the highest relevance score from the matching inner documents to the parent.
- `min`: Assigns the lowest relevance score from the matching inner documents to the parent.
- `sum`: Sums the relevance scores of all matching inner documents.
- `none`: Ignores the relevance scores of inner documents and assigns a score of `0` to the parent document.
Default is `avg`. | | `inner_hits` | Optional | If provided, returns the underlying hits that matched the query. | ## Next steps - Learn more about [retrieving inner hits]({{site.url}}{{site.baseurl}}/search-plugins/searching-data/inner-hits/).