How to use query_string with the filter in elasticsearch? - elasticsearch

I have a simple query
GET data/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"last_name": "test"
}
},
{
"bool": {
"should": {
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
}
}
]
}
}
}
I would like to change the query_string to a filter. I'm not sure how to convert
{
"bool": {
"should": {
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
}
}
into something like
"filter": {
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
and make sure it filters by all this cities henderson OR Boulder City OR Sloan and by all this fields city_*.keyword
Any ideas?

Change
{
"bool": {
"should": {
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
}
}
to
{
"bool": {
"filter": {
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
}
}
Does this get your desired behavior? Using the same query under a filter should give you the same results as should, but the scoring will not be weighted by the query.
Edit - One more recommendation I would make is to adjust your query to this:
GET data/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"last_name": "test"
}
}
],
"filter": [
{
"query_string": {
"query": "henderson OR Boulder City OR Sloan",
"fields": [
"city_*"
]
}
}
]
}
}
}
Edit 2 - You may be able to move away from using query_string, does this give you any speed increase? (you could change should to the "shoulds" to be nested within a filter as well if you want them unscored)
GET data/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"last_name": "test"
}
}
],
"should": [
{
"match": {
"city_*": "henderson"
}
},
{
"match": {
"city_*": "Boulder City"
}
},
{
"match": {
"city_*": "Sloan"
}
}
]
}
}
}

Related

In Elastic search, how do I match by multiple objects in an array of objects?

I'm following the example here:
https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html
The following query:
GET my_index/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }}
]
}
}
}
}
}
matches one record as expected. Suppose instead I only want to return documents which have both 'John Smith' and 'Alice White' as a user.
I have tried:
GET my_index/_search
{
"query": {
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{ "match": { "user.first": "Alice" }},
{ "match": { "user.last": "White" }},
{ "match": { "user.first": "John" }},
{ "match": { "user.last": "Smith" }}
]
}
}
}
}
}
but this returns zero results. How can I get documents with both 'Alice White' and 'John Smith' (which should just be the same document returned in the original result)?
You should use a bool query to combine more than one clause. With your syntax you are searching for a doc that has both Alice and John as value in the same field. Try, indeed:
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "Alice"
}
},
{
"match": {
"user.last": "White"
}
}
]
}
}
}
},
{
"nested": {
"path": "user",
"query": {
"bool": {
"must": [
{
"match": {
"user.first": "John"
}
},
{
"match": {
"user.last": "Smith"
}
}
]
}
}
}
}
]
}
}
}

Elasticsearch filtered query with script for term frequency

I'm using the attachment plugin: https://github.com/elastic/elasticsearch-mapper-attachments
I'm able to find documents with a specific word in 1 or more fields but unable to filter documents with a lower term frequency than searched for.
This works:
POST /crm/employee/_search
{
"query": {"filtered": {
"query": {"match": {
"employee.cv.content": "transitie"
}},
"filter": {
"bool": {
"should": [
{"terms": {
"employee.listEmployeeType.id": [
2
]
}}
]
}
}
}},
"highlight": {"fields": {"employee.cv.content" : {}}}
}
After a long search, I've found the following:
"script": {
"script": "crm['employee.cv.content'][lookup].tf() > occurrence",
"params": {
"lookup": "transitie",
"occurrence": 1
}
},
I'm unable to implement it unfortunately. I hope i've explained the issue good enough for someone to give me a push in the right direction!
{
"query": {
"filtered": {
"query": {
"match": {
"employee.cv.content": "transitie"
}
},
"filter": {
"bool": {
"should": [
{
"terms": {
"employee.listEmployeeType.id": [
2
]
}
}
],
"must": [
{
"script": {
"script": "_index['employee.cv.content'][lookup].tf() > occurrence",
"params": {
"lookup": "transitie",
"occurrence": 1
}
}
}
]
}
}
}
},
"highlight": {
"fields": {
"employee.cv.content": {}
}
}
}

Elastic Search - OR querying for non matches

I'm having trouble querying in elastic search. I'm searching over a specific set of data defined by the state_id, and then wanting to return all the states which do not have either one of the cities defined by the identifiers below.
The query below returns 18 results with just "city_id_1", and 0 results with "city_id_2". With both though, I return 0 results (since "city_id_2" is on every state record). What I want to do is still return the 18 results, but query over both cities.
I feel like my query should be working, and basically doing a NOT (A or B) style query, equivalent to NOT A and NOT B, but basically the 0 results seems to be overriding the 18.
Is there a way I can change my query to get the results I want, or is this something elasticsearch cannot do?
{
"query": {
"bool": {
"must": [
{ "terms": { "state_id": ["4ca16f80-da79-11e5-9874-64006a4f57cb"]}}
],
"must_not": [
{
"nested": {
"path": "cities",
"query": {
"bool": {
"should": [
{"term": { "cities.identifier": "city_id_1"}},
{"term": { "cities.identifier": "city_id_2"}}
]
}
}
}
}
]
}
},
"size": 10
}
Try this on for size. Elasticsearch is silly. The filter needs to be in each of the nested queries.
{
"query": {
"bool": {
"should": [
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "cities",
"query": {
"term": { "cities.identifier": "city_id_1"}
}
}
}
],
"filter":[
{
"term":{
"state_id":"4ca16f80-da79-11e5-9874-64006a4f57cb"
}
}
]
}
}
},
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "cities",
"query": {
"term": { "cities.identifier": "city_id_2"}
}
}
}
],
"filter":[
{
"term":{
"state_id":"4ca16f80-da79-11e5-9874-64006a4f57cb"
}
}
]
}
}
}
]
}
},
"size": 10
}
If you want NOT A AND NOT B behaviour you need to make a little change
{
"query": {
"bool": {
"must": [
{ "terms": { "state_id": ["4ca16f80-da79-11e5-9874-64006a4f57cb"]}}
],
"must_not": [
{
"nested": {
"path": "cities",
"query": {
"bool": {
"must": [ ====> Use must instead of should
{"term": { "cities.identifier": "city_id_1"}},
{"term": { "cities.identifier": "city_id_2"}}
]
}
}
}
}
]
}
},
"size": 10
}
This will exclude those record which will have both city_id_1 and city_id_2.
As per my understanding, you are looking our for NOT A or NOT B kind of a clause. Please check the query below and see if it fits your requirement
{
"query": {
"bool": {
"must": [
{ "terms": { "state_id": ["4ca16f80-da79-11e5-9874-64006a4f57cb"]}}
],
"should": [
{
"nested": {
"path": "cities",
"query": {
"bool": {
"must_not": [
{"term": { "cities.identifier": "city_id_1"}}
]
}
}
}
},
{
"nested": {
"path": "cities",
"query": {
"bool": {
"must_not": [
{"term": { "cities.identifier": "city_id_2"}}
]
}
}
}
}
],
"minimum_number_should_match": 1
}
},
"size": 10
}

Bool query not working as expected

POST /test/topic/_search
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "Predisposition",
"fields": [
"_all"
]
}
},
{
"multi_match": {
"query": "thrombosis",
"fields": [
"_all"
]
}
}
],
"should": [
{
"multi_match": {
"query": "cancer",
"fields": [
"_all"
]
}
}
]
}
}
}
My understanding of the above query is that it must match on predisposition AND thrombosis OR cancer, however I'm only getting a handful of documents that match on predisposition AND thrombosis, I was expecting lots of cancer documents but have zero. What am I missing?
The must needs to always match. should will only give a boost to the score if it matches.
Also, there is another case when there are no must statements and in this case at least one should must match.
I think you are looking for the following, instead:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "Predisposition",
"fields": [
"_all"
]
}
},
{
"multi_match": {
"query": "thrombosis",
"fields": [
"_all"
]
}
}
]
}
},
{
"bool": {
"must": [
{
"multi_match": {
"query": "cancer",
"fields": [
"_all"
]
}
}
]
}
}
]
}
}
}
The way you are searching is, documents must have predisposition AND thrombosis regardless of cancer because they are inside must filter.
You basically need to wrap your must clause inside should clause like this
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "predisposition",
"fields": "_all"
}
},
{
"multi_match": {
"query": "thrombosis",
"fields": "_all"
}
}
]
}
},
{
"multi_match": {
"query": "cancer",
"fields": "_all"
}
}
]
}
}
}
This will give you the desired results.

Elasticsearch Parse Exception for boolean queries

I'm trying to create queries similar to kibana queries in elasticsearch lucene queries. What I'm basically trying to do is matching some phrases. For example; my kibana query looks like this:(+"anna smith") AND ( (+"university"), (+"chairman"), (+"women rights")) It searches "anna smith" as must and one of the other phrases as should(there should be at least one of them exist in the text). I wrote a query to do this but it gives "elasticsearch parse exception:expected field name but got start_object". How can I solve this. Here is my query;
{
"query": {
"bool": {
"must": {
"match": {
"text": {
"query": "anna smith",
"operator": "and"
}
}
}
},
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"text": {
"query": "university",
"boost": 2
}
}
},
{
"match": {
"text": {
"query": "chairman",
"boost": 2
}
}
}
]
}
}]
}}}}
Your second query at the bottom cannot be there, it needs to be inside the first bool/must like this
{
"query": {
"bool": {
"must": [
{
"match": {
"text": {
"query": "anna smith",
"operator": "and"
}
}
},
{
"bool": {
"should": [
{
"match": {
"text": {
"query": "university",
"boost": 2
}
}
},
{
"match": {
"text": {
"query": "chairman",
"boost": 2
}
}
}
]
}
}
]
}
}
}

Resources