Combining Multiple Queries with 'OR' or 'AND' in Elasticsearch - 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

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
}

Nested query to find child containing term X and child's parent contains term Y

I have a mapping like this
{
"properties" : {
"text" : {
"type" : "nested",
"properties": {
"header": {
"type" : "text"
},
"nodes": {
"type": "nested",
"properties": {
"subheader" : {
"type" : "text"
},
"nodes" : {
"type" : "nested"
}
}
}
}
}
}
}
I'll like to return the documents where the innermost child text.nodes.nodes contains some term 'X' if and only if that child's parent text.nodes.subheader contains some term 'Y'
Here's a reproducible gist, where I expect that a search for 'SUPERFRAGILISTIC' in the child, and 'Restrictions' in the subheader should return only document 2.
It is now returning both documents.
From the gist, my query right now looks like:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "text.nodes",
"query": {
"bool": {
"must": [
{
"match": {
"text.nodes.subheader": {
"query": "Restrictions"
}
}
}
]
}
}
}
},
{
"nested": {
"path": "text.nodes.nodes",
"query": {
"bool": {
"must": [
{
"match": {
"text.nodes.nodes.content": {
"query": "SUPERFRAGILISTIC"
}
}
}
]
}
}
}
}
]
}
}
}
In order to find a result with two conditions that are contained in the same json node of a single document, you need to nest the second condition in the first one. With this query you'll get only document2:
{
"query":{
"bool":{
"must":[
{
"nested":{
"path":"text.nodes",
"query":{
"bool":{
"must":[
{
"match":{
"text.nodes.subheader":{
"query":"Restrictions"
}
}
},
{
"nested":{
"path":"text.nodes.nodes",
"query":{
"bool":{
"must":[
{
"match":{
"text.nodes.nodes.content":{
"query":"SUPERFRAGILISTIC"
}
}
}
]
}
}
}
}
]
}
}
}
}
]
}
}
}

How to do mulitple text search in elastic search

I want to do multiple text search in same field
for example in sub_cat_seo_url field i want to get 'english-news' and 'business-news' filter by language and region
when i tried like below code it is not working
{
"query":{
"filtered":{
"query":{
"query_string":{
"query":[
"english-news",
"business-news"
],
"fields":[
"sub_cat_seo_url"
]
}
},
"filter":{
"bool":{
"must":[
{
"term":{
"lang":"en"
}
},
{
"term":{
"region":"1"
}
}
]
}
}
}
}
}
For single text search it is working fine
{
"query":{
"filtered":{
"query":{
"query_string":{
"query":"english-news",
"fields":[
"sub_cat_seo_url"
]
}
},
"filter":{
"bool":{
"must":[
{
"term":{
"lang":"en"
}
},
{
"term":{
"region":"1"
}
}
]
}
}
}
}
}
Please help what have to change in my code, to do multi text search in same field (or operation)
Thanks
Thanigaivelan
Try out this
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "\"english-news\" AND \"business-news\"",
"fields": [
"sub_cat_seo_url"
]
}
},
"filter": {
"bool": {
"must": [
{
"term": {
"lang": "en"
}
},
{
"term": {
"region": "1"
}
}
]
}
}
}
}
}

Elastic search filtered query, query part being ignored?

I'm building up the following search in code, the idea being that it filters down the set of matches then queries this so I can add score based on certain fields. For some reason the filter part works but whatever I put in the query (i.e. in the below I have no index sdfsdfsdf) it still returns anything matching the filter.
Is the syntax wrong?
{
"query":{
"filtered":{
"query":{
"bool":{
"must":{
"match":{
"sdfsdfsdf":{
"query":"4",
"boost":2.0
}
}
}
},
"filter":{
"bool":{
"must":[
{
"terms":{
"_id":[
"55f93ead5df34f1900abc20b",
"55f8ab0226ec4bb216d7c938",
"55dc4e949dcf833308c63d6b"
]
}
},
{
"range":{
"published_date":{
"lte":"now"
}
}
}
],
"must_not":{
"terms":{
"_id":[
"55f0a799acccc28204a5058c"
]
}
}
}
}
}
}
}
}
Your filter is not at the right level. It should not be inside query but at the same level as query like this:
{
"query": {
"filtered": {
"query": { <--- query and filter at the same level
"bool": {
"must": {
"match": {
"sdfsdfsdf": {
"query": "4",
"boost": 2
}
}
}
}
},
"filter": { <--- query and filter at the same level
"bool": {
"must": [
{
"terms": {
"_id": [
"55f93ead5df34f1900abc20b",
"55f8ab0226ec4bb216d7c938",
"55dc4e949dcf833308c63d6b"
]
}
},
{
"range": {
"published_date": {
"lte": "now"
}
}
}
],
"must_not": {
"terms": {
"_id": [
"55f0a799acccc28204a5058c"
]
}
}
}
}
}
}
}
You need to replace sdfsdfsdf with your existing field name in your type, e.g. title, otherwise I think it will fallback to match_all query.
"match":{
"title":{
"query": "some text here",
"boost":2.0
}
}

ElasticSearch nested [AND OR] filter

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

Resources