Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add filtering to fieldcaps endpoint #83636

Merged
merged 17 commits into from
Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/changelog/83636.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
pr: 83636
summary: Add filtering to fieldcaps endpoint
area: Search
type: enhancement
issues:
- 82966
9 changes: 9 additions & 0 deletions docs/reference/search/field-caps.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=index-ignore-unavailab
(Optional, Boolean) If `true`, unmapped fields are included in the response.
Defaults to `false`.

`filters`::
(Optional, string) Comma-separated list of filters to apply to the response. The
following filters are supported: +metadata,-metadata,-parent,-nested,-multifield
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the + notation supported only for metadata? Would it make sense to expand on what each one of these mean, with a link to the relevant docs explanation for each one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll expand the docs. The idea is that - and + work in much the same way they do in our query parsers = - means 'must not match', and + means 'must match'. So you can ask for only metadata, or to exclude metadata. For the others it doesn't make much sense to do anything except exclude them, with the exception of parent where it sort of makes sense to say 'include parent data as well as everything else', so a bare parent term is supported.


`types`::
(Optional, string) Comma-separated list of field types to include. Any fields that
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shall we link the docs page with all of the field types here? Maybe also include an example at the end of the sentence?

do not match one of these types will be excluded from the results. Defaults to empty,
meaning that all field types are returned.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more question, just to double check: types:keyword means either runtime or indexed field, no distinction between the two for field_caps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keyword runtime fields return KeywordFieldMapper.CONTENT_TYPE as their family name (which is what is actually checked here). I also wonder if it's worth adding a -runtime, +runtime pair of filters. I know you don't like making it too obvious what is runtime and what isn't, but I think it can still be helpful for clients.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's wait for them to ask? :)


[[search-field-caps-api-request-body]]
==== {api-request-body-title}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@
"type":"boolean",
"default":false,
"description":"Indicates whether unmapped fields should be included in the response."
},
"filters": {
"type":"list",
"description":"An optional set of filters: can include +metadata,-metadata,-nested,-multifield,-parent"
},
"types": {
"type": "list",
"description":"Only return results for fields that have one of the types in the list"
}
},
"body":{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
---
setup:
- skip:
version: "- 8.1.99"
reason: Field type filters were added in 8.2
- do:
indices.create:
index: test1
body:
mappings:
properties:
text:
type: text
fields:
keyword:
type: keyword
keyword:
type: keyword
number:
type: double
geo:
type: geo_point
misc:
type: text
object:
type: object
properties:
nested1 :
type : text
index: false
nested2:
type: float
doc_values: false
level1:
type: nested
properties:
level2:
type: object
properties:
leaf1:
type: text
index: false
runtime:
misc.keyword:
type: keyword

- do:
indices.create:
index: test2
body:
mappings:
properties:
text:
type: text
keyword:
type: keyword
number:
type: double
date:
type: date
geo:
type: geo_point
object:
type: object
properties:
nested1 :
type : text
index: true
nested2:
type: float
doc_values: true
level1:
type: nested
properties:
level2:
type: object
properties:
leaf1:
type: text
index: false
- do:
indices.create:
index: test3
body:
mappings:
properties:
text:
type: text
keyword:
type: keyword
number:
type: long
date:
type: date
non_indexed_date:
type: date
index: false
non_indexed_keyword:
type: keyword
index: false
non_indexed_boolean:
type: boolean
index: false
non_indexed_ip:
type: ip
index: false
non_indexed_geo_point:
type: geo_point
index: false
geo:
type: keyword
object:
type: nested
properties:
nested1 :
type : long
index: false
nested2:
type: keyword
doc_values: false
---
"No filters includes all the following fields":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'

- is_true: fields.object
- is_true: fields.text
- is_true: fields.text\\.keyword
- is_true: fields._seq_no
- is_true: fields.level1\\.level2\\.leaf1
- is_true: fields.level1

---
"Exclude parent objects":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
filters: '-parent'

- is_true: fields.object\\.nested1
- is_false: fields.object

---
"Exclude metadata fields":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
filters: '-metadata'

- is_false: fields._seq_no

---
"Exclude non-metadata fields":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
filters: '+metadata'

- is_true: fields._seq_no
- is_false: fields.text

---
"Exclude nested fields":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
filters: '-nested'

- is_false: fields.level1
- is_false: fields.level1\\.level2\\.leaf1

---
"Exclude multifields":
- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
filters: '-multifield'

- is_false: fields.text\\.keyword
- is_true: fields.misc\\.keyword

---
"Field type filters":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test case for multiple values in the fields parameter?

- do:
field_caps:
index: 'test1,test2,test3'
fields: '*'
types: 'text,keyword,long'

- is_false: fields.date
- is_false: fields.non_indexed_boolean
- is_true: fields.non_indexed_keyword
- is_true: fields.misc

---
"Field type filters with field name restrictions":
- do:
field_caps:
index: 'test1,test2,test3'
fields: 'non_*,text'
types: 'text,keyword,long'

- is_false: fields.non_indexed_boolean
- is_true: fields.non_indexed_keyword
- is_false: fields.misc
- is_true: fields.text
Loading