How to write query to find data in nested and not nested fields together - elasticsearch

I would like to find multiple field search.
So:
GET my_doc/_search
{
"query": {
"multi_match" : {
"query": "text",
"fields": [ "state", "city"]
}
}
}
Generally this query works, but it does not search in the nested fields.
But this one works only for nested fields:
GET my_doc*/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "images",
"score_mode": "max",
"query": {
"bool": {
"must": [
{"match": {"images.description": "Subject" }},
{"match": {"images.Number": "10004" }}
]
}
}
}
}
]
}
}
}
My question is:
How to write query to search everywhere - Just to join my queries together to find in the "images" location too.

I've found solution, just to join queries:
GET my_doc*/_search
{
"query": {
"bool": {
"must": [
{
"multi_match" : {
"query": "LAKE",
"fields": [ "state", "city"]
}
},
{
"nested": {
"path": "images",
"score_mode": "max",
"query": {
"bool": {
"must": [
{"match": {"images.description": "Subject" }},
{"match": {"images.Number": "10004" }}
]
}
}
}
}
]
}
}
}

Related

Elasticsearch must_not inside nested query

My elastic search index having nested fields. and I want to use must, which contains a must_not query in it with a nested query. I have tried a must_not query separately in the following way:
{
"bool": {
"must_not": [{
"nested": {
"path": "fields",
"query": {
"terms": {
"fields.value.raw": [
"200"
]
}
}
}
}]
}
}
above query gives me a valid result but when I was tried this with must query then it will not give me any result.I am using following query:
{
"bool": {
"must": [{
"nested": {
"path": "fields",
"query": {
"bool": {
"must": [{
"match": {
"fields.uid": "number"
}
}, {
"bool": {
"must_not": [{
"nested": {
"path": "fields",
"query": {
"terms": {
"fields.value.raw": [
"200"
]
}
}
}
}]
}
}]
}
}
}
}]
}
}
above query not gives me a valid result. What is wrong in above query?
How I can use a must_not in must with nested query?
You should use must and must_not in the same bool query.
{
"bool": {
"must_not": [{
"nested": {
"path": "fields",
"query": {
"terms": {
"fields.value.raw": [
"200"
]
}
}
}
}],
"must": [{
"match": {
"fields.uid": "number"
}
}]
}
}

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
}
}
}
]
}
}
]
}
}
}

How to distinguish hits of several should clauses

I have a query with several "should" clauses:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "<condition1>"
}
},
{
"query_string": {
"query": "<condition1>"
}
}
]
}
},
}
},
"size": 1000,
"sort": [
{
"#timestamp": {
"order": "asc"
}
}
]
}
How can I find out which query results were produced by condition1, and which by condition2? Is it possible to inject a field with different values for different conditions, or distinguish hits in any other way?
You can use named queries to achieve this.
{
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "<condition1>",
"_name": "sub_query_1"
}
},
{
"query_string": {
"query": "<condition1>",
"_name": "sub_query_2"
}
}
]
}
}
}
You result will then contain a matched_filters array with either sub_query_1, sub_query_2, or both in it.
Update
Play link: https://www.found.no/play/gist/af1a1fa2b5cf3aa279b1

Resources