ElasticSearch nested [AND OR] filter - elasticsearch

I have a query that I'm struggling with in ElasticSearch. In fact, I have two queries, the first works, but the second doesn't.
Here's the basics 1st query, which is fine (the query is actually quite a bit bigger than this, I've stripped it down for ease of understanding):
{
"query": {
"filtered": {
"query": {
"match_all":{}
},
"filter": {
"and": [{
"term":{
"relatedID":"214"
}
},
{
"term":{
"relatedType":"deal"
}
}]
}
}
}
}
So basically, grab all items where relatedID == 214 && relatedType == "deal"
However, what I'd also like to do, is this:
{
"query": {
"filtered": {
"query": {
"match_all":{}
},
"filter": {
"and": [{
{
"or":[{
"and":[{
"relatedID":"528"
},
{
"relatedType":"company"
}]
},{
"and":[{
"relatedID":"214"
},
{
"relatedType":"deal"
}
]}
]}
]}
}
}
}
}
}
}
So basically, grab everything where either deal AND 214, or company AND 528.
This is where I seem to be getting stuck.
As I said, there's a lot more in the query (see full query below, which might help understand why I've tried to structure it above):
{
"query":{
"filtered":{
"query":{
"match_all":{}
},
"filter":{
"and":[
{
"or":[
{
"term":{
"timeSensitive":false
}
}
,
{
"range":{
"validTo":{
"gt":"20140513T153030Z"
},
"validFrom":{
"lt":"20140513T153030Z"
}
}
}
]
}
,
{
"term":{
"categoryTree.NAME":"Promotions"
}
}
,
{
"or":[
{
"and":[
{
"relatedID":"528"
}
,
{
"relatedType":"company"
}
]
}
,
{
"and":[
{
"relatedID":"214"
}
,
{
"relatedType":"deal"
}
]
}
]
}
,
{
"terms":{
"permissions": ["member","supplier"]
}
}
,
{
"term":{
"siteID":6
}
}
]
}
}
}
}
}
}

Its syntax error.The problem is You didn't mentions term filter inside (and,or)filter.
try to use boolean filter and query its more faster than (and or) filter.
[AND OR] Filter
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"or": [
{
"and": [
{
"term": {
"relatedID": "528"
}
},
{
"term": {
"relatedType": "company"
}
}
]
},
{
"and": [
{
"term": {
"relatedID": "214"
}
},
{
"term": {
"relatedType": "deal"
}
}
]
}
]
}
]
}
}
}
}
Same Query i converted in to bool filter
curl -XPOST "http://localhost:9200/try/_search" -d'
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"relatedID":"528"
}
},
{
"term": {
"relatedType":"company"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"relatedID":"214"
}
},
{
"term": {
"relatedType":"deal"
}
}
]
}
}
]
}
}
}
}
}'

Related

elasticsearch nested query, more than one one object should meet conditions

I have some questions about nested query.
Here is my example. The mapping is {"user":"nested"}.The exist data just like this:
{
"user": [
{
"first":"John",
"last":"Smith"
},
{
"first":"Alice",
"last":"White"
}
]
}
How do I create a query to find this document that meets all the conditions:
the first object of user that its "first" is "John" and "last" is "Smith";
the second object of user that its "first" is "Alice" and "last" is "White"
Try with below query :
{
"query":{
"bool":{
"filter":[
{
"bool":{
"must":[
{
"bool":{
"must":[
{
"nested":{
"query":{
"bool":{
"must":[
{
"match_phrase":{
"user.first":{
"query":"John"
}
}
},
{
"match_phrase":{
"user.last":{
"query":"Smith"
}
}
}
]
}
},
"path":"user"
}
},
{
"nested":{
"query":{
"bool":{
"must":[
{
"match_phrase":{
"user.first":{
"query":"Alice"
}
}
},
{
"match_phrase":{
"user.last":{
"query":"White"
}
}
}
]
}
},
"path":"user"
}
}
]
}
}
]
}
}
]
}
}
}
Below query is what you are looking for. You simply need to have two nested queries, one for each conditions you've mentioned, combined in a bool using must clause.
Note that I'm assuming that the fields user.first and user.last are of text type having standard analyzer
POST <your_index_name>
{
"query":{
"bool":{
"must":[
{
"nested":{
"path":"user",
"query":{
"bool":{
"must":[
{
"match":{
"user.first":"john"
}
},
{
"match":{
"user.last":"smith"
}
}
]
}
}
}
},
{
"nested":{
"path":"user",
"query":{
"bool":{
"must":[
{
"match":{
"user.first":"alice"
}
},
{
"match":{
"user.last":"white"
}
}
]
}
}
}
}
]
}
}
}
Hope this helps!
The answer is:
{
"query": {
"bool": {
"must": [
{
"has_parent": {
"parent_type": "doc",
"query": {
"bool": {
"must": [
{
"terms": {
"id": [
713
]
}
},
{
"range": {
"created": {
"lte": "now/d"
}
}
},
{
"range": {
"expires": {
"gte": "now/d"
}
}
}
]
}
}
}
},
{
"nested": {
"path": "prices",
"query": {
"bool": {
"filter": [
{
"term": {
"prices.id_prcknd": 167
}
}
]
}
}
}
},
{
"term": {
"doc_type": "item"
}
},
{
"bool": {
"should": [
{
"term": {
"have_prices": true
}
},
{
"term": {
"is_folder": true
}
}
]
}
}
],
"must_not": {
"exists": {
"field": "folder"
}
}
}
},
"sort": [
{
"is_folder": {
"order": "desc"
}
},
{
"title_low.order": {
"order": "asc"
}
}
],
"size": 1000
}

How to query a nested object with combined AND and OR logic?

How should this expression be written as a query:
(attributes.id = 14 OR attributes.id = 15) AND (attributes.id = 4843 OR attributes.id = 4859)
The nested object looks like this:
{
"attributes":[
{
"id":14,
"type":"color",
"name":"Sort",
"version":1
},
{
"id":15,
"type":"color",
"name":"Sølv",
"version":1
},
{
"id":2031,
"type":"brand",
"name":"Jimmy Choo",
"version":1
},
{
"id":4843,
"type":"size",
"name":"36x28",
"version":1
},
{
"id":4859,
"type":"size",
"name":"38x36",
"version":1
},
{
"id":4927,
"type":"size",
"name":"60J",
"version":1
},
{
"id":4958,
"type":"size",
"name":"75F",
"version":1
}
]
}
I've tried using this query - among many - without any luck:
{
"query":{
"nested":{
"path":"attributes",
"query":{
"bool":{
"should":[
{
"terms":{
"attributes.id":[
14,
15
]
}
},
{
"terms":{
"attributes.id":[
4843,
4859
]
}
}
],
"minimum_should_match":2
}
}
}
}
}
The above query returns zero results.
Any help would be appreciated.
{
"query":{
"nested":{
"path":"attributes",
"query":{
"bool":{
"must":[{
"bool": {
"should": [
{
"term": {
"attributes.id": 14
}
},{
"term": {
"attributes.id": 15
}
}
]
}
},{
"bool": {
"should": [
{
"term": {
"attributes.id": 4843
}
},{
"term": {
"attributes.id": 4859
}
}
]
}
}
]
}
}
}
This should work.
I got the answer on Elastic Stack by Daniel_Penning:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "variants.attributes",
"query": {
"terms": {
"variants.attributes.id": [
14, 15
]
}
}
}
},
{
"nested": {
"path": "variants.attributes",
"query": {
"terms": {
"variants.attributes.id": [
4843, 4859
]
}
}
}
}
]
}
}
}

Combining must_not in ElasticSearch Query

I'm currently struggling with an ElastSearch query which currently looks the following:
...
"query": {
"bool": {
"must_not": [
{
"term": {
"bool-facet.criteria1": {
"value": false
}
}
},
{
"term": {
"bool-facet.criteria2": {
"value": false
}
}
}
]
}
}
...
So now when either criteria1 OR criteria2 matches, the documents are ignored. How must the query look like so that only documents that match criteria1 AND criteria2 are ignored?
If you want simple AND-behavior, then just nest another bool query inside of it:
"query": {
"bool": {
"must_not": [
{
"bool": {
"filter": [
{
"term": {
"bool-facet.criteria1": false
}
},
{
"term": {
"bool-facet.criteria2": false
}
}
]
}
}
]
}
}
Note that by using the filter (as it's a yes/no question with no scoring needed, but if you wanted scoring, then you would use must instead of filter) you get the desired AND behavior. This changes the question to "not(any document that has criteria1 == false AND criteria2 == false)".
The following arrangement worked for me on a similar query in 5.5.1:
"query": {
"bool": {
"must": [
{
"bool":{
"must_not":{
"term":{
"bool-facet.criteria1": false
}
}
}
},
{
"bool":{
"must_not":{
"term":{
"bool-facet.criteria2": true
}
}
}
}
]
}
}
The other answers may have been correct for other versions, but did not work for me in 5.5.1.
Since updating elasticsearch version was not possible I had to find another solution. This is what worked for me:
"query": {
"bool": {
"must_not" : [
{
"query": {
"bool": {
"must": [
{
"term": {
"bool-facet.criteria1": false
}
},
{
"term": {
"bool-facet.criteria2": false
}
}
]
}
}
}
]
}
}
This behavior worked for me under 6.5.4:
GET model/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "field1"
}
},
{
"exists": {
"field": "field2"
}
},
{
"exists": {
"field": "field3"
}
}
]
}
}
}

Combine Elastic Search Queries

I have the following 2 queries:
GET places/_search
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"approved": false
}
}
]
}
}
}
}
}
GET places/_search
{
"query": {
"filtered": {
"filter": {
"geo_bounding_box": {
"loc": {
"top_left": "54.6152065515344, -6.09334913041994",
"bottom_right": "54.5754258987271, -5.76633420732423"
}
}
}
}
}
}
Both work fine, however I am having issues combining the queries and was wondering if anyone could help. Basically I want to retuen all items within the bounding box specified, where the "approved" property is false.
You can keep your filtered query and merge both conditions simply like this inside in a bool/mustfilter
curl -XPOST localhost:9200/places/_search -d '{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"approved": false
}
},
{
"geo_bounding_box": {
"loc": {
"top_left": "54.6152065515344, -6.09334913041994",
"bottom_right": "54.5754258987271, -5.76633420732423"
}
}
}
]
}
}
}
}
}'

Combining Multiple Queries with 'OR' or 'AND' in Elasticsearch

I have two distinct query, and I want to combine them with an 'OR'/'AND' in between. How do I do that?
For example, for the given queries
I just want to run Query1 OR Query2 in the elasticsearch.
Query1:
{
"query": {
"filtered": {
"query": {
"query_string":{
"query":"Batman",
"default_operator":"AND",
"fields"::[
"Movies._all"
]
}
},
"filter": {
"bool": {
"must": [
{
"query":{
"filtered":{
"filter":{
"and":[
{
"term":{
"cast.firstName":"Christian "
}
},
{
"term":{
"cast.lastName":"Bale"
}
}
]
}
}
}
}
]
}
}
}
}
}
Query2:
{
"query": {
"filtered": {
"query": {
"query_string":{
"query":"Dark Knight",
"default_operator":"AND",
"fields"::[
"Movies._all"
]
}
},
"filter": {
"bool": {
"must": [
{
"query":{
"filtered":{
"filter":{
"and":[
{
"term":{
"director.firstName":"Christopher"
}
},
{
"term":{
"director.lastName":"Nolan"
}
}
]
}
}
}
}
]
}
}
}
}
}
You need to use a bool query
Something like below will work fine -
{
"query" : {
"bool" : {
"must" : [
{ // Query1 },
{ // Query2}
]
}
}
}
Use must for AND and should for OR

Resources