2014-10-13 03:41:55 -04:00
|
|
|
[[search-request-inner-hits]]
|
|
|
|
=== Inner hits
|
|
|
|
|
2015-08-06 11:24:29 -04:00
|
|
|
The <<mapping-parent-field, parent/child>> and <<nested, nested>> features allow the return of documents that
|
2016-08-01 08:09:54 -04:00
|
|
|
have matches in a different scope. In the parent/child case, parent document are returned based on matches in child
|
|
|
|
documents or child document are returned based on matches in parent documents. In the nested case, documents are returned
|
2014-10-13 03:41:55 -04:00
|
|
|
based on matches in nested inner objects.
|
|
|
|
|
2014-12-02 14:51:06 -05:00
|
|
|
In both cases, the actual matches in the different scopes that caused a document to be returned is hidden. In many cases,
|
2015-09-30 05:07:51 -04:00
|
|
|
it's very useful to know which inner nested objects (in the case of nested) or children/parent documents (in the case
|
2014-12-02 14:51:06 -05:00
|
|
|
of parent/child) caused certain information to be returned. The inner hits feature can be used for this. This feature
|
2014-10-13 03:41:55 -04:00
|
|
|
returns per search hit in the search response additional nested hits that caused a search hit to match in a different scope.
|
|
|
|
|
2016-01-10 15:51:29 -05:00
|
|
|
Inner hits can be used by defining an `inner_hits` definition on a `nested`, `has_child` or `has_parent` query and filter.
|
2014-12-03 12:18:34 -05:00
|
|
|
The structure looks like this:
|
2014-10-13 03:41:55 -04:00
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
2015-01-19 12:56:25 -05:00
|
|
|
"<query>" : {
|
|
|
|
"inner_hits" : {
|
|
|
|
<inner_hits_options>
|
2014-10-13 03:41:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2016-08-11 06:35:40 -04:00
|
|
|
If `inner_hits` is defined on a query that supports it then each search hit will contain an `inner_hits` json object with the following structure:
|
2014-10-13 03:41:55 -04:00
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_index": ...,
|
|
|
|
"_type": ...,
|
|
|
|
"_id": ...,
|
|
|
|
"inner_hits": {
|
|
|
|
"<inner_hits_name>": {
|
|
|
|
"hits": {
|
|
|
|
"total": ...,
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_type": ...,
|
|
|
|
"_id": ...,
|
|
|
|
...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
]
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
==== Options
|
|
|
|
|
|
|
|
Inner hits support the following options:
|
|
|
|
|
|
|
|
[horizontal]
|
|
|
|
`from`:: The offset from where the first hit to fetch for each `inner_hits` in the returned regular search hits.
|
|
|
|
`size`:: The maximum number of hits to return per `inner_hits`. By default the top three matching hits are returned.
|
|
|
|
`sort`:: How the inner hits should be sorted per `inner_hits`. By default the hits are sorted by the score.
|
2014-12-03 12:18:34 -05:00
|
|
|
`name`:: The name to be used for the particular inner hit definition in the response. Useful when multiple inner hits
|
|
|
|
have been defined in a single search request. The default depends in which query the inner hit is defined.
|
|
|
|
For `has_child` query and filter this is the child type, `has_parent` query and filter this is the parent type
|
|
|
|
and the nested query and filter this is the nested path.
|
2014-10-13 03:41:55 -04:00
|
|
|
|
|
|
|
Inner hits also supports the following per document features:
|
|
|
|
|
|
|
|
* <<search-request-highlighting,Highlighting>>
|
|
|
|
* <<search-request-explain,Explain>>
|
|
|
|
* <<search-request-source-filtering,Source filtering>>
|
|
|
|
* <<search-request-script-fields,Script fields>>
|
2016-06-21 05:27:27 -04:00
|
|
|
* <<search-request-docvalue-fields,Doc value fields>>
|
2014-10-13 03:41:55 -04:00
|
|
|
* <<search-request-version,Include versions>>
|
|
|
|
|
|
|
|
[[nested-inner-hits]]
|
|
|
|
==== Nested inner hits
|
|
|
|
|
|
|
|
The nested `inner_hits` can be used to include nested inner objects as inner hits to a search hit.
|
|
|
|
|
|
|
|
The example below assumes that there is a nested object field defined with the name `comments`:
|
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
{
|
|
|
|
"query" : {
|
|
|
|
"nested" : {
|
|
|
|
"path" : "comments",
|
|
|
|
"query" : {
|
2016-08-01 08:09:54 -04:00
|
|
|
"match" : {"comments.message" : "[actual query]"}
|
2014-12-03 12:18:34 -05:00
|
|
|
},
|
|
|
|
"inner_hits" : {} <1>
|
2014-10-13 03:41:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2014-12-03 12:18:34 -05:00
|
|
|
<1> The inner hit definition in the nested query. No other options need to be defined.
|
2014-10-13 03:41:55 -04:00
|
|
|
|
|
|
|
An example of a response snippet that could be generated from the above search request:
|
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
...
|
|
|
|
"hits": {
|
|
|
|
...
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_index": "my-index",
|
|
|
|
"_type": "question",
|
|
|
|
"_id": "1",
|
|
|
|
"_source": ...,
|
|
|
|
"inner_hits": {
|
2014-12-03 12:18:34 -05:00
|
|
|
"comments": { <1>
|
2014-10-13 03:41:55 -04:00
|
|
|
"hits": {
|
|
|
|
"total": ...,
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_nested": {
|
|
|
|
"field": "comments",
|
|
|
|
"offset": 2
|
|
|
|
},
|
|
|
|
"_source": ...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
...
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2014-12-03 12:18:34 -05:00
|
|
|
<1> The name used in the inner hit definition in the search request. A custom key can be used via the `name` option.
|
|
|
|
|
2014-10-13 03:41:55 -04:00
|
|
|
The `_nested` metadata is crucial in the above example, because it defines from what inner nested object this inner hit
|
|
|
|
came from. The `field` defines the object array field the nested hit is from and the `offset` relative to its location
|
|
|
|
in the `_source`. Due to sorting and scoring the actual location of the hit objects in the `inner_hits` is usually
|
|
|
|
different than the location a nested inner object was defined.
|
|
|
|
|
|
|
|
By default the `_source` is returned also for the hit objects in `inner_hits`, but this can be changed. Either via
|
|
|
|
`_source` filtering feature part of the source can be returned or be disabled. If stored fields are defined on the
|
|
|
|
nested level these can also be returned via the `fields` feature.
|
|
|
|
|
|
|
|
An important default is that the `_source` returned in hits inside `inner_hits` is relative to the `_nested` metadata.
|
|
|
|
So in the above example only the comment part is returned per nested hit and not the entire source of the top level
|
2016-02-09 05:07:32 -05:00
|
|
|
document that contained the comment.
|
2014-10-13 03:41:55 -04:00
|
|
|
|
2015-01-12 07:11:46 -05:00
|
|
|
[[hierarchical-nested-inner-hits]]
|
|
|
|
==== Hierarchical levels of nested object fields and inner hits.
|
|
|
|
|
|
|
|
If a mapping has multiple levels of hierarchical nested object fields each level can be accessed via dot notated path.
|
|
|
|
For example if there is a `comments` nested field that contains a `votes` nested field and votes should directly be returned
|
2016-02-09 05:07:32 -05:00
|
|
|
with the root hits then the following path can be defined:
|
2015-01-12 07:11:46 -05:00
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
{
|
|
|
|
"query" : {
|
|
|
|
"nested" : {
|
|
|
|
"path" : "comments.votes",
|
2016-08-01 08:09:54 -04:00
|
|
|
"query" : { ... },
|
2015-01-12 07:11:46 -05:00
|
|
|
"inner_hits" : {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
|
|
|
This indirect referencing is only supported for nested inner hits.
|
|
|
|
|
2014-10-13 03:41:55 -04:00
|
|
|
[[parent-child-inner-hits]]
|
|
|
|
==== Parent/child inner hits
|
|
|
|
|
|
|
|
The parent/child `inner_hits` can be used to include parent or child
|
|
|
|
|
|
|
|
The examples below assumes that there is a `_parent` field mapping in the `comment` type:
|
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
{
|
|
|
|
"query" : {
|
|
|
|
"has_child" : {
|
|
|
|
"type" : "comment",
|
|
|
|
"query" : {
|
2016-08-01 08:09:54 -04:00
|
|
|
"match" : {"message" : "[actual query]"}
|
2014-12-03 12:18:34 -05:00
|
|
|
},
|
|
|
|
"inner_hits" : {} <1>
|
2014-10-13 03:41:55 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
--------------------------------------------------
|
|
|
|
|
2014-12-03 12:18:34 -05:00
|
|
|
<1> The inner hit definition like in the nested example.
|
2014-10-13 03:41:55 -04:00
|
|
|
|
|
|
|
An example of a response snippet that could be generated from the above search request:
|
|
|
|
|
|
|
|
[source,js]
|
|
|
|
--------------------------------------------------
|
|
|
|
...
|
|
|
|
"hits": {
|
|
|
|
...
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_index": "my-index",
|
|
|
|
"_type": "question",
|
|
|
|
"_id": "1",
|
|
|
|
"_source": ...,
|
|
|
|
"inner_hits": {
|
|
|
|
"comment": {
|
|
|
|
"hits": {
|
|
|
|
"total": ...,
|
|
|
|
"hits": [
|
|
|
|
{
|
|
|
|
"_type": "comment",
|
|
|
|
"_id": "5",
|
|
|
|
"_source": ...
|
|
|
|
},
|
|
|
|
...
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
...
|
2016-08-01 08:09:54 -04:00
|
|
|
--------------------------------------------------
|