Parent-join and nested functions allow matching documents to be returned in different ranges. In the parent/child case, the parent document is returned based on a match in the child document, or the child document is returned based on a match in the parent document. In the case of nesting, documents are returned based on a match in the nested internal object.

In both cases, the actual matches in different scopes cause the documents to be returned to be hidden. In many cases, it is useful to know which internally nested objects (in the case of nesting) or child/parent documents (in the case of parent/child) cause certain information to be returned. The internal hit feature can be used for this purpose. This feature returns additional nested hits for each search hit in the search response that result in a search hit match in a different range.

You can use internal matching by defining inner_hits definitions on nested has_child or has_parent queries and filters. The structure is as follows:

"<query>" : {
  "inner_hits" : {
    <inner_hits_options>
  }
}
Copy the code

If you define inner_hits on a query that supports it, then each search hit contains an inner_hits JSON object with the following structure:

"hits": [
  {
    "_index": ...,
    "_type": ...,
    "_id": ...,
    "inner_hits": {
      "<inner_hits_name>": {
        "hits": {
          "total": ...,
          "hits": [
            {
              "_type": ...,
              "_id": ...,
               ...
            },
            ...
          ]
        }
      }
    },
    ...
  },
  ...
]
Copy the code

Options

Internal click count supports the following options:

parameter instructions
from The offset from the first match of each inner_hits in the returned regular search results is retrieved
size The maximum number of matches returned per inner_hits. By default, the first three matches are returned
sort How you should sort the internal matches by inner_hits. By default, hits are sorted by score
name The name used in the response for a specific internal match definition. Useful when multiple internal matches are defined in a single search request. The default value depends on the query that defines the internal match. For has_child queries and filters, this is a subtype; Has_parent query and filter, which is the parent type; Nested queries and filters, which are nested paths.

Internal hits also support each of the following document features:

  • Highlighting
  • Explain
  • Search fields
  • Source filtering
  • Script fields
  • Doc value fields
  • Include versions
  • Include Sequence Numbers and Primary Terms

Nested inner hits

Nested inner_hits can be used to contain nested inner objects as internal hits for search hits.

PUT test { "mappings": { "properties": { "comments": { "type": "nested" } } } } PUT test/_doc/1? refresh { "title": "Test title", "comments": [ { "author": "kimchy", "number": 1 }, { "author": "nik9000", "number": 2 } ] } POST test/_search { "query": { "nested": { "path": "comments", "query": { "match": { "comments.number": 2}}, "inner_hits": {} # inner match definition in nested query. No additional options are required}}}Copy the code

An example of a response fragment that can be generated from the above search request:

{... , "hits" : {" total ": {" value" : 1, the "base" : "eq"}, "max_score" : 1.0, "hits" : [{" _index ":" test ", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" :..., "inner_hits" : {" comments ": Hits: {"total": {"value": 1, "relation": "eq"}, "max_score": 1.0, "hits": [ { "_index": "test", "_type": "_doc", "_id": "1", "_nested": { "field": "comments", "offset": 1 }, "_score": 1.0, the "_source" : {" author ":" nik9000 ", "number" : 2}}}}}}}}]]Copy the code

The _NESTED metadata is critical in the above example because it defines which internally nested object the internal hit came from. This field defines the object array field from which the nested match comes and the offset relative to its position in _source. Because of sorting and scoring, the actual location of the hit object in inner_hits is usually different from the location of the nested inner object.

By default, _source is also returned for the hit object in inner_hits, but this can be changed. Part of the source can be returned or disabled through the _source filtering function. If stored fields are defined at the nesting level, they can also be returned through the fields function.

An important default value is that the _source returned by inner_hits within the hit is relative to the _nested metadata. So in the example above, each nested match returns only the comment portion, not the entire source of the top-level document that contains the comment.

Nested inner hits and _source

Nested documents do not have a _source field because the entire document source is stored under the _source field along with the root document. To include only the source of the nested document, the source of the root document is analyzed and only the relevant bits of the nested document are included as the source in the internal match. Doing this for each matched nested document affects the time it takes to execute the entire search request, especially if the size and the size of the internal match are set higher than the default. To avoid the relatively expensive extraction of source code for nested internal matches, you can disable source code and rely only on document value fields. Like this:

PUT test { "mappings": { "properties": { "comments": { "type": "nested" } } } } PUT test/_doc/1? refresh { "title": "Test title", "comments": [ { "author": "kimchy", "text": "comment text" }, { "author": "nik9000", "text": "words words words" } ] } POST test/_search { "query": { "nested": { "path": "comments", "query": { "match": { "comments.text": "words" } }, "inner_hits": { "_source": false, "docvalue_fields": [ "comments.text.keyword" ] } } } }Copy the code

Hierarchical levels of nested object fields and inner hits

If the map has layers of nested object fields, then each layer can be accessed through the dot-tag path. For example, if you have a Comments nested field that contains a votes nested field, and the vote should be returned directly with the root match, you can define the following path:

PUT test { "mappings": { "properties": { "comments": { "type": "nested", "properties": { "votes": { "type": "nested" } } } } } } PUT test/_doc/1? refresh { "title": "Test title", "comments": [ { "author": "kimchy", "text": "comment text", "votes": [] }, { "author": "nik9000", "text": "words words words", "votes": [ {"value": 1 , "voter": "kimchy"}, {"value": -1, "voter": "other"} ] } ] } POST test/_search { "query": { "nested": { "path": "comments.votes", "query": { "match": { "comments.votes.voter": "kimchy" } }, "inner_hits" : {} } } }Copy the code

Looks like:

{... , "hits" : {" total ": {" value" : 1, the "base" : "eq"}, "max_score" : 0.6931471, "hits" : [{" _index ":" test ", "_type" : "_doc", "_id" : "1", "_score" : 0.6931471, "_source" :..., "inner_hits" : {" comments. Votes ": {" hits" : {" total ": {" value ": 1," base ":" eq "}, "max_score" : 0.6931471, "hits" : [{" _index ":" test ", "_type" : "_doc", "_id" : "1", "_nested": { "field": "comments", "offset": 1, "_nested": { "field": "votes", "offset": 0 } }, "_score": 0.6931471, the "_source" : {" value ": 1," voter ":" kimchy "}}}}}}}}]]Copy the code

Nested internal hits support only this indirect reference.

Parent/child inner hits

Parent/child inner_hits can be used to include parents or children:

PUT test { "mappings": { "properties": { "my_join_field": { "type": "join", "relations": { "my_parent": "my_child" } } } } } PUT test/_doc/1? refresh { "number": 1, "my_join_field": "my_parent" } PUT test/_doc/2? routing=1&refresh { "number": 1, "my_join_field": { "name": "my_child", "parent": "1" } } POST test/_search { "query": {" has_child ": {" type" : "my_child", "query" : {" match ": {" number" : 1}}, "inner_hits" : {} # internal hit definition is similar to the contents of the nested example}}}Copy the code

An example of a response fragment that can be generated from the above search request:

{... , "hits" : {" total ": {" value" : 1, the "base" : "eq"}, "max_score" : 1.0, "hits" : [{" _index ":" test ", "_type" : "_doc", "_id" : "1", "_score" : 1.0, "_source" : {" number ": 1," my_join_field ":" my_parent} ", "inner_hits" : {" my_child ": {" hits" : {" total ": {" value" : 1, the "base" : "eq"}, "max_score" : 1.0, "hits" : [{" _index ": "Test", "_type" : "_doc", "_id" : "2", "_score" : 1.0, "_routing" : "1", "_source" : {" number ": 1," my_join_field ": { "name": "my_child", "parent": "1" } } } ] } } } } ] } }Copy the code

See the website: www.elastic.co/guide/en/el…