Fetch meta fields in FetchFieldsPhase using ValueFetcher (#106325)

Here we extract the logic to populate metadata fields such as _ignored, _routing, _size and the deprecated _type into FetchFieldsPhase so that we can use the ValueFetcher interface to retrieve field values. This allows us to fetch values no matter if the Mapper uses stored or doc values.
This commit is contained in:
Salvatore Campagna 2024-04-15 11:02:18 +02:00 committed by GitHub
parent b9322da325
commit 4dfcb0897e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 456 additions and 68 deletions

View file

@ -0,0 +1,159 @@
---
"_ignored field through get api using stored_fields":
- do:
indices.create:
index: test
body:
mappings:
properties:
keyword:
type: keyword
ignore_above: 5
ip:
type: ip
ignore_malformed: true
value:
type: long
ignore_malformed: true
- do:
index:
index: test
id: 1
refresh: true
body:
keyword: foo
ip: 192.168.0.1
value: 23
- do:
index:
index: test
id: 2
refresh: true
body:
keyword: foobar
ip: garbage
value: missing
- do:
index:
index: test
id: 3
refresh: true
body:
keyword:
- foo
- bar
- foobar
ip:
- 10.10.1.1
- 192.8.1.2
- 199.199.300.999
value:
- 1
- 2
- ops
- do:
get:
index: test
id: 1
- match: {_index: "test"}
- match: {_id: "1"}
- match: {_version: 1}
- match: {found: true}
- match:
_source:
keyword: foo
ip: 192.168.0.1
value: 23
- is_false: fields
- do:
get:
index: test
id: 2
- match: { _index: "test" }
- match: { _id: "2" }
- match: { _version: 1 }
- match: { found: true }
- match:
_source:
ip: garbage
keyword: foobar
value: missing
- is_false: fields
- do:
get:
index: test
id: 3
- match: { _index: "test" }
- match: { _id: "3" }
- match: { _version: 1 }
- match: { found: true }
- match:
_source:
ip:
- 10.10.1.1
- 192.8.1.2
- 199.199.300.999
keyword:
- foo
- bar
- foobar
value:
- 1
- 2
- ops
- is_false: fields
- do:
get:
index: test
id: 1
stored_fields:
- _ignored
- match: { _index: "test" }
- match: { _id: "1" }
- match: { _version: 1 }
- match: { found: true }
- match: { _ignored: null}
- do:
get:
index: test
id: 2
stored_fields:
- _ignored
- match: { _index: "test" }
- match: { _id: "2" }
- match: { _version: 1 }
- match: { found: true }
- match:
_ignored:
- ip
- keyword
- value
- do:
get:
index: test
id: 3
stored_fields:
- _ignored
- match: { _index: "test" }
- match: { _id: "3" }
- match: { _version: 1 }
- match: { found: true }
- match:
_ignored:
- ip
- keyword
- value

View file

@ -22,8 +22,8 @@ setup:
---
fetch fields:
- skip:
version: ' - 8.5.99'
reason: stored fields phase added in 8.6
version: ' - 8.13.99'
reason: fetch fields and stored_fields using ValueFetcher
- do:
search:
@ -44,17 +44,21 @@ fetch fields:
- match: { profile.shards.0.fetch.debug.stored_fields: [_id, _routing, _source] }
- length: { profile.shards.0.fetch.children: 2 }
- match: { profile.shards.0.fetch.children.0.type: FetchFieldsPhase }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.1.type: StoredFieldsPhase }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
---
fetch source:
- skip:
version: ' - 8.5.99'
reason: stored fields phase added in 8.6
version: ' - 8.13.99'
reason: fetch fields and stored_fields using ValueFetcher
- do:
search:
@ -71,20 +75,21 @@ fetch source:
- gt: { profile.shards.0.fetch.breakdown.load_stored_fields_count: 0 }
- gt: { profile.shards.0.fetch.breakdown.load_stored_fields: 0 }
- match: { profile.shards.0.fetch.debug.stored_fields: [_id, _routing, _source] }
- length: { profile.shards.0.fetch.children: 2 }
- match: { profile.shards.0.fetch.children.0.type: FetchSourcePhase }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.0.debug.fast_path: 1 }
- match: { profile.shards.0.fetch.children.1.type: StoredFieldsPhase }
- length: { profile.shards.0.fetch.children: 3 }
- match: { profile.shards.0.fetch.children.0.type: FetchFieldsPhase }
- match: { profile.shards.0.fetch.children.1.type: FetchSourcePhase }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.1.debug.fast_path: 1 }
- match: { profile.shards.0.fetch.children.2.type: StoredFieldsPhase }
---
fetch nested source:
- skip:
version: ' - 8.5.99'
reason: stored fields phase added in 8.6
version: ' - 8.13.99'
reason: fetch fields and stored_fields using ValueFetcher
- do:
indices.create:
@ -135,24 +140,25 @@ fetch nested source:
- gt: { profile.shards.0.fetch.breakdown.load_stored_fields_count: 0 }
- gt: { profile.shards.0.fetch.breakdown.load_stored_fields: 0 }
- match: { profile.shards.0.fetch.debug.stored_fields: [_id, _routing, _source] }
- length: { profile.shards.0.fetch.children: 3 }
- match: { profile.shards.0.fetch.children.0.type: FetchSourcePhase }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.0.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.1.type: InnerHitsPhase }
- length: { profile.shards.0.fetch.children: 4 }
- match: { profile.shards.0.fetch.children.0.type: FetchFieldsPhase }
- match: { profile.shards.0.fetch.children.1.type: FetchSourcePhase }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.1.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.2.type: StoredFieldsPhase }
- match: { profile.shards.0.fetch.children.2.type: InnerHitsPhase }
- gt: { profile.shards.0.fetch.children.2.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.2.breakdown.next_reader: 0 }
- gt: { profile.shards.0.fetch.children.2.breakdown.next_reader_count: 0 }
- gt: { profile.shards.0.fetch.children.2.breakdown.next_reader: 0 }
- match: { profile.shards.0.fetch.children.3.type: StoredFieldsPhase }
---
disabling stored fields removes fetch sub phases:
- skip:
version: ' - 7.15.99'
reason: fetch profiling implemented in 7.16.0
reason: fetch profiling implemented in 7.16.0
- do:
search:

View file

@ -0,0 +1,159 @@
---
setup:
- do:
indices.create:
index: test
body:
settings:
index.number_of_shards: 1
mappings:
properties:
stored_keyword:
type: keyword
store: true
keyword:
type: keyword
stored_value:
type: integer
store: true
value:
type: integer
ignored_keyword:
type: keyword
ignore_above: 3
ignored_value:
type: integer
ignore_malformed: true
- do:
index:
index: test
id: "1"
refresh: true
body:
stored_keyword: "stored_keyword_value"
keyword: "keyword_value"
stored_value: 10
value: 100
ignored_keyword: "foobar"
ignored_value: foobar
---
fetch stored fields:
- do:
search:
index: test
body:
stored_fields: [ stored_keyword, stored_value, keyword, value ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields.stored_keyword.0: "stored_keyword_value" }
- match: { hits.hits.0.fields.stored_value.0: 10 }
- match: { hits.hits.0.fields.keyword: null }
- match: { hits.hits.0.fields.value: null }
---
fetch fields:
- do:
search:
index: test
body:
fields: [ stored_keyword, stored_value, keyword, value ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields.stored_keyword.0: "stored_keyword_value" }
- match: { hits.hits.0.fields.stored_value.0: 10 }
- match: { hits.hits.0.fields.keyword.0: "keyword_value" }
- match: { hits.hits.0.fields.value.0: 100 }
---
fetch fields and stored fields:
- do:
search:
index: test
body:
fields: [ keyword, stored_value ]
stored_fields: [ stored_keyword, value ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields.stored_keyword.0: "stored_keyword_value" }
- match: { hits.hits.0.fields.stored_value.0: 10 }
- match: { hits.hits.0.fields.keyword.0: "keyword_value" }
- match: { hits.hits.0.fields.value: null }
---
fetch _ignored via stored_fields:
- do:
search:
index: test
body:
stored_fields: [ _ignored ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields._ignored: null }
- match: { hits.hits.0._ignored.0: "ignored_keyword" }
- match: { hits.hits.0._ignored.1: "ignored_value" }
---
fetch _ignored via fields:
- do:
search:
index: test
body:
fields: [ _ignored ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields._ignored.0: "ignored_keyword" }
- match: { hits.hits.0.fields._ignored.1: "ignored_value" }
- match: { hits.hits.0._ignored.0: "ignored_keyword" }
- match: { hits.hits.0._ignored.1: "ignored_value" }
---
fetch _seq_no via stored_fields:
- do:
search:
index: test
body:
stored_fields: [ _seq_no ]
- match: { hits.total.value: 1 }
- match: { hits.hits.0.fields._seq_no: null }
- match: { hits.hits.0._seq_no: null }
---
fetch _seq_no via fields:
- do:
catch: "request"
search:
index: test
body:
fields: [ _seq_no ]
# This should be `unauthorized` (401) or `forbidden` (403) or at least `bad request` (400)
# while instead it is mapped to an `internal_server_error (500)`
- match: { status: 500 }
- match: { error.root_cause.0.type: unsupported_operation_exception }
---
fetch fields with none stored_fields:
- skip:
version: " - 7.99.99"
reason: "from illegal_argument_exception to action_request_validation_exception"
- do:
catch: "bad_request"
search:
index: test
body:
stored_fields: _none_
fields: [stored_keyword, keyword, stored_value, value, ignored_keyword, ignored_value, _ignored]
- match: { status: 400 }
- match: { error.root_cause.0.type: action_request_validation_exception }