Im making a query that can filter out content based on certain fields and I had this.
{
"from" : 0,
"size" : 10,
"query" : {
"bool" : {
"filter" : [
{
"bool" : {
"must_not" : [
{
"terms" : {
"metadata.subtype" : [
"Type1"
],
"boost" : 1.0
}
}
],
}
}
],
}
},
}
With a object like this
{
id: "SomeId" <- Text
metadata: {
subtype: "Type1" <- Keyword
}
}
And that works fine for that one field, but if instead of metadata.subtype
I used id
it no longer works unless I make it id.keyword
.
But then metadata.subtype.keyword
does not work and I dont understand why. Can you not use .keyword
with fields that are indexed as keywords?
CodePudding user response:
terms
query works with fields of keyword
type, so it won't match your id
field if it is text
.
If you really want to filter against text field, use another query, e.g. match
. But if you want to actually use terms
query, you need to change the type of id
field to keyword.
Another common approach is to define a field of text
type, but add a keyword
subfield so that it can also be matched by term
and terms
queries.
See: https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html
Here's an example index mapping that would probably match your needs.
{
"mapping": {
"properties": {
"id": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"metadata.subtype": {
"type": "keyword"
}
}
}
}
Then you can filter with any of the following queries:
{ "match": { "id": "text" } }
{ "terms": { "id.raw": "text" } }
{ "terms": { "metadata.subtype": "value" } }