Reputation: 1669
So I have the following ElasticSearch query:
"query": {
"bool": {
"must": [
{
"nested": {
"path": "specs",
"query": {
"bool": {
"must": [
{
"match": {
"specs.battery": "2 hours"
}
}
],
"minimum_should_match": 1
}
}
}
},
{
"terms": {
"category_ids": [
16405
]
}
}
]
}
}
At the moment it returns all documents that have either 2
or hours
in specs.battery
value. How could I modify this query, so that it only returns documents, that have exact phrase 2 hours
in specs.battery
field? As well, I would like to have the ability to have multiple phrases (2hrs, 2hours, 3 hours etc etc). Is this achievable?
Upvotes: 2
Views: 2897
Reputation: 3874
The data in elasticsearch is by default tokenized when you index it. This means the result of indexing the expression "2 hours" will be 2 tokens mapped to the same document. However there will not be a one token "2 hours", therefore it will either search 2 or hours or even will not find it if you use a filtered query.
To have Elasticseach consider "2 hours" as one expression you need to define specs.battery as not_analyzedin your mapping like follows:
curl -XPOST localhost:9200/your_index -d '{
"mappings" : {
"your_index_type" : {
"properties" : {
...
"battery" : { "type" : "string", "index":"not_analyzed" }
...
}
}
}
}'
Then you can have an exact match using a filtered query as follows:
curl -XGET 'http://localhost:9200/_all/_search?pretty=true' -d '
{
"query": {
"filtered" : {
"filter" : {
"term": {
"battery": "2 hours"
}
}
}
}
}'
Then you'll have an exact match.
More details at: https://www.elastic.co/guide/en/elasticsearch/guide/current/_finding_exact_values.html
If on the other hand you absolutely need your field to be analyzed or work with an existing index that you can't change, you still have a solution by using the operator "and" like follows:
curl -XGET localhost:9200/your_index' -d '
{
"query": {
"match": {
"battery": {
"query": "2 hours",
"operator": "and"
}
}
}
}'
In the last option, you may have understood already that if you have a document that has "2 hours and something else" , the document will still be matched so this is not as precise as with an "not_analyzed" field.
More details on the last topic at:
https://www.elastic.co/guide/en/elasticsearch/guide/current/match-multi-word.html
Upvotes: 4