Skip to content

Commit 8fff763

Browse files
author
Christoph Büscher
authored
[Docs] Add nested fields handling in fields API (#68657)
This change adds a paragraph on the different response format for nested fields in the fields API and adds an example snippet. Related to #63709
1 parent 936abca commit 8fff763

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

docs/reference/search/search-your-data/retrieve-selected-fields.asciidoc

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,161 @@ no dedicated array type, and any field could contain multiple values. The
167167
a specific order. See the mapping documentation on <<array, arrays>> for more
168168
background.
169169

170+
[discrete]
171+
[[search-fields-nested]]
172+
==== Handling of nested fields
173+
174+
The `fields` response for <<nested,`nested` fields>> is slightly different from that
175+
of regular object fields. While leaf values inside regular `object` fields are
176+
returned as a flat list, values inside `nested` fields are grouped to maintain the
177+
independence of each object inside the original nested array.
178+
For each entry inside a nested field array, values are again returned as a flat list
179+
unless there are other `nested` fields inside the parent nested object, in which case
180+
the same procedure is repeated again for the deeper nested fields.
181+
182+
Given the following mapping where `user` is a nested field, after indexing
183+
the following document and retrieving all fields under the `user` field:
184+
185+
[source,console]
186+
--------------------------------------------------
187+
PUT my-index-000001
188+
{
189+
"mappings": {
190+
"properties": {
191+
"group" : { "type" : "keyword" },
192+
"user": {
193+
"type": "nested",
194+
"properties": {
195+
"first" : { "type" : "keyword" },
196+
"last" : { "type" : "keyword" }
197+
}
198+
}
199+
}
200+
}
201+
}
202+
203+
PUT my-index-000001/_doc/1?refresh=true
204+
{
205+
"group" : "fans",
206+
"user" : [
207+
{
208+
"first" : "John",
209+
"last" : "Smith"
210+
},
211+
{
212+
"first" : "Alice",
213+
"last" : "White"
214+
}
215+
]
216+
}
217+
218+
POST my-index-000001/_search
219+
{
220+
"fields": ["*"],
221+
"_source": false
222+
}
223+
--------------------------------------------------
224+
225+
the response will group `first` and `last` name instead of
226+
returning them as a flat list.
227+
228+
[source,console-result]
229+
----
230+
{
231+
"took": 2,
232+
"timed_out": false,
233+
"_shards": {
234+
"total": 1,
235+
"successful": 1,
236+
"skipped": 0,
237+
"failed": 0
238+
},
239+
"hits": {
240+
"total": {
241+
"value": 1,
242+
"relation": "eq"
243+
},
244+
"max_score": 1.0,
245+
"hits": [{
246+
"_index": "my-index-000001",
247+
"_id": "1",
248+
"_score": 1.0,
249+
"fields": {
250+
"group" : ["fans"],
251+
"user": [{
252+
"first": ["John"],
253+
"last": ["Smith"],
254+
},
255+
{
256+
"first": ["Alice"],
257+
"last": ["White"],
258+
}
259+
]
260+
}
261+
}]
262+
}
263+
}
264+
----
265+
// TESTRESPONSE[s/"took": 2/"took": $body.took/]
266+
// TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
267+
// TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
268+
269+
Nested fields will be grouped by their nested paths, no matter the pattern used to retrieve them.
270+
For example, querying only for the `user.first` field in the example above:
271+
272+
[source,console]
273+
--------------------------------------------------
274+
POST my-index-000001/_search
275+
{
276+
"fields": ["user.first"],
277+
"_source": false
278+
}
279+
--------------------------------------------------
280+
// TEST[continued]
281+
282+
will return only the users first name but still maintain the structure of the nested `user` array:
283+
284+
[source,console-result]
285+
----
286+
{
287+
"took": 2,
288+
"timed_out": false,
289+
"_shards": {
290+
"total": 1,
291+
"successful": 1,
292+
"skipped": 0,
293+
"failed": 0
294+
},
295+
"hits": {
296+
"total": {
297+
"value": 1,
298+
"relation": "eq"
299+
},
300+
"max_score": 1.0,
301+
"hits": [{
302+
"_index": "my-index-000001",
303+
"_id": "1",
304+
"_score": 1.0,
305+
"fields": {
306+
"user": [{
307+
"first": ["John"],
308+
},
309+
{
310+
"first": ["Alice"],
311+
}
312+
]
313+
}
314+
}]
315+
}
316+
}
317+
----
318+
// TESTRESPONSE[s/"took": 2/"took": $body.took/]
319+
// TESTRESPONSE[s/"max_score" : 1.0/"max_score" : $body.hits.max_score/]
320+
// TESTRESPONSE[s/"_score" : 1.0/"_score" : $body.hits.hits.0._score/]
321+
322+
However, when the `fields` pattern targets the nested `user` field directly, no
323+
values will be returned since the pattern doesn't match any leaf fields.
324+
170325
[discrete]
171326
[[retrieve-unmapped-fields]]
172327
==== Retrieving unmapped fields

0 commit comments

Comments
 (0)