|
1 | 1 | [[query-dsl-has-child-query]] |
2 | 2 | === Has Child Query |
3 | 3 |
|
4 | | -Returns parent documents whose <<parent-join,joined>> child documents match a |
5 | | -provided query. You can create parent-child relationships between documents in |
6 | | -the same index using a <<parent-join,join>> field mapping. |
7 | | - |
8 | | -[WARNING] |
9 | | -==== |
10 | | -Because it performs a join, the `has_child` is slow compared to other queries. |
11 | | -Its performance degrades as the number of matching child documents pointing to |
12 | | -unique parent documents increases. Each `has_child` query in a search can |
13 | | -increase query time significantly. |
14 | | -
|
15 | | -If you care about query performance, do not use this query. If you need to use |
16 | | -the `has_child` query, use it as rarely as possible. |
17 | | -==== |
18 | | - |
19 | | -[[has-child-query-ex-request]] |
20 | | -==== Example request |
21 | | - |
22 | | -[[has-child-index-setup]] |
23 | | -===== Index setup |
24 | | -To use the `has_child` query, your index must include a <<parent-join,join>> |
25 | | -field mapping. For example: |
| 4 | +The `has_child` filter accepts a query and the child type to run against, and |
| 5 | +results in parent documents that have child docs matching the query. Here is |
| 6 | +an example: |
26 | 7 |
|
27 | 8 | [source,js] |
28 | | ----- |
29 | | -PUT /my_index |
| 9 | +-------------------------------------------------- |
| 10 | +GET /_search |
30 | 11 | { |
31 | | - "mappings": { |
32 | | - "properties" : { |
33 | | - "my-join-field" : { |
34 | | - "type" : "join", |
35 | | - "relations": { |
36 | | - "parent": "child" |
| 12 | + "query": { |
| 13 | + "has_child" : { |
| 14 | + "type" : "blog_tag", |
| 15 | + "query" : { |
| 16 | + "term" : { |
| 17 | + "tag" : "something" |
37 | 18 | } |
38 | 19 | } |
39 | 20 | } |
40 | 21 | } |
41 | 22 | } |
42 | | -
|
43 | | ----- |
| 23 | +-------------------------------------------------- |
44 | 24 | // CONSOLE |
45 | | -// TESTSETUP |
46 | 25 |
|
47 | | -[[has-child-query-ex-query]] |
48 | | -===== Example query |
| 26 | +Note that the `has_child` is a slow query compared to other queries in the |
| 27 | +query dsl due to the fact that it performs a join. The performance degrades |
| 28 | +as the number of matching child documents pointing to unique parent documents |
| 29 | +increases. If you care about query performance you should not use this query. |
| 30 | +However if you do happen to use this query then use it as little as possible. |
| 31 | +Each `has_child` query that gets added to a search request can increase query |
| 32 | +time significantly. |
| 33 | + |
| 34 | +[float] |
| 35 | +==== Scoring capabilities |
| 36 | + |
| 37 | +The `has_child` also has scoring support. The |
| 38 | +supported score modes are `min`, `max`, `sum`, `avg` or `none`. The default is |
| 39 | +`none` and yields the same behaviour as in previous versions. If the |
| 40 | +score mode is set to another value than `none`, the scores of all the |
| 41 | +matching child documents are aggregated into the associated parent |
| 42 | +documents. The score type can be specified with the `score_mode` field |
| 43 | +inside the `has_child` query: |
49 | 44 |
|
50 | 45 | [source,js] |
51 | | ----- |
| 46 | +-------------------------------------------------- |
52 | 47 | GET /_search |
53 | 48 | { |
54 | 49 | "query": { |
55 | 50 | "has_child" : { |
56 | | - "type" : "child", |
| 51 | + "type" : "blog_tag", |
| 52 | + "score_mode" : "min", |
57 | 53 | "query" : { |
58 | | - "match_all" : {} |
59 | | - }, |
60 | | - "max_children": 10, |
61 | | - "min_children": 2, |
62 | | - "score_mode" : "min" |
| 54 | + "term" : { |
| 55 | + "tag" : "something" |
| 56 | + } |
| 57 | + } |
63 | 58 | } |
64 | 59 | } |
65 | 60 | } |
66 | | ----- |
| 61 | +-------------------------------------------------- |
67 | 62 | // CONSOLE |
68 | 63 |
|
69 | | -[[has-child-top-level-params]] |
70 | | -==== Top-level parameters for `has_child` |
71 | | - |
72 | | -`type`:: |
73 | | -(string) Required. Name of the child relationship mapped for the |
74 | | -<<parent-join,join>> field. |
75 | | - |
76 | | -`query`:: |
77 | | -(query object) Required. Query you wish to run on child documents of the `type` |
78 | | -field. If a child document matches the search, the query returns the parent |
79 | | -document. |
80 | | - |
81 | | -`ignore_unmapped`:: |
82 | | -+ |
83 | | --- |
84 | | -(boolean) Optional. Indicates whether to ignore an unmapped `type` and not return |
85 | | -any documents instead of an error. Defaults to `false`. |
86 | | - |
87 | | -If `false`, {es} returns an error if the `type` is unmapped. |
88 | | - |
89 | | -You can use this parameter to query multiple indices that may not contain the |
90 | | -`type`. |
91 | | --- |
| 64 | +[float] |
| 65 | +[[min-max-children]] |
| 66 | +==== Min/Max Children |
92 | 67 |
|
93 | | -`max_children`:: |
94 | | -(integer) Optional. Maximum number of child documents that match the `query` |
95 | | -allowed for a returned parent document. If the parent document exceeds this |
96 | | -limit, it is excluded from the search results. |
| 68 | +The `has_child` query allows you to specify that a minimum and/or maximum |
| 69 | +number of children are required to match for the parent doc to be considered |
| 70 | +a match: |
97 | 71 |
|
98 | | -`min_children`:: |
99 | | -(integer) Optional. Minimum number of child documents that match the `query` |
100 | | -required to match the query for a returned parent document. If the parent |
101 | | -document does not meet this limit, it is excluded from the search results. |
102 | | - |
103 | | -`score_mode`:: |
104 | | -+ |
105 | | --- |
106 | | -(string) Optional. Indicates how scores for matching child documents affect the |
107 | | -root parent document's <<query-filter-context,relevance score>>. Valid values |
108 | | -are: |
109 | | - |
110 | | -`none` (Default):: |
111 | | -Do not use the relevance scores of matching child documents. The query assigns |
112 | | -parent documents a score of `0`. |
113 | | - |
114 | | -`avg`:: |
115 | | -Use the mean relevance score of all matching child documents. |
| 72 | +[source,js] |
| 73 | +-------------------------------------------------- |
| 74 | +GET /_search |
| 75 | +{ |
| 76 | + "query": { |
| 77 | + "has_child" : { |
| 78 | + "type" : "blog_tag", |
| 79 | + "score_mode" : "min", |
| 80 | + "min_children": 2, <1> |
| 81 | + "max_children": 10, <1> |
| 82 | + "query" : { |
| 83 | + "term" : { |
| 84 | + "tag" : "something" |
| 85 | + } |
| 86 | + } |
| 87 | + } |
| 88 | + } |
| 89 | +} |
| 90 | +-------------------------------------------------- |
| 91 | +// CONSOLE |
| 92 | +<1> Both `min_children` and `max_children` are optional. |
116 | 93 |
|
117 | | -`max`:: |
118 | | -Uses the highest relevance score of all matching child documents. |
| 94 | +The `min_children` and `max_children` parameters can be combined with |
| 95 | +the `score_mode` parameter. |
119 | 96 |
|
120 | | -`min`:: |
121 | | -Uses the lowest relevance score of all matching child documents. |
| 97 | +[float] |
| 98 | +==== Ignore Unmapped |
122 | 99 |
|
123 | | -`sum`:: |
124 | | -Add together the relevance scores of all matching child documents. |
125 | | --- |
| 100 | +When set to `true` the `ignore_unmapped` option will ignore an unmapped `type` |
| 101 | +and will not match any documents for this query. This can be useful when |
| 102 | +querying multiple indexes which might have different mappings. When set to |
| 103 | +`false` (the default value) the query will throw an exception if the `type` |
| 104 | +is not mapped. |
126 | 105 |
|
127 | | -[[has-child-query-notes]] |
128 | | -==== Notes |
| 106 | +[float] |
| 107 | +==== Sorting |
129 | 108 |
|
130 | | -[[has-child-query-performance]] |
131 | | -===== Sorting |
132 | | -You cannot sort the results of a `has_child` query using standard |
133 | | -<<search-request-sort,sort options>>. |
| 109 | +Parent documents can't be sorted by fields in matching child documents via the |
| 110 | +regular sort options. If you need to sort parent document by field in the child |
| 111 | +documents then you should use the `function_score` query and then just sort |
| 112 | +by `_score`. |
134 | 113 |
|
135 | | -If you need to sort returned documents by a field in their child documents, use |
136 | | -a `function_score` query and sort by `_score`. For example, the following query |
137 | | -sorts returned documents by the `click_count` field of their child documents. |
| 114 | +Sorting blogs by child documents' `click_count` field: |
138 | 115 |
|
139 | 116 | [source,js] |
140 | | ----- |
| 117 | +-------------------------------------------------- |
141 | 118 | GET /_search |
142 | 119 | { |
143 | 120 | "query": { |
144 | 121 | "has_child" : { |
145 | | - "type" : "child", |
| 122 | + "type" : "blog_tag", |
| 123 | + "score_mode" : "max", |
146 | 124 | "query" : { |
147 | 125 | "function_score" : { |
148 | 126 | "script_score": { |
149 | 127 | "script": "_score * doc['click_count'].value" |
150 | 128 | } |
151 | 129 | } |
152 | | - }, |
153 | | - "score_mode" : "max" |
| 130 | + } |
154 | 131 | } |
155 | 132 | } |
156 | 133 | } |
157 | | ----- |
| 134 | +-------------------------------------------------- |
158 | 135 | // CONSOLE |
0 commit comments