elasticsearch boolean search syntax - elasticsearch

Can anybody please explain why this elasticsearch syntax is incorrect. I'm struggling to get my head around basic syntaxing
This works
"query": {
"filtered": {
"filter": {
"bool" : {
"should": {
"terms": {
"headline":["aut"]
}
},
"must": {
"range": {
"date_at" : {
"gt": "1900-01-01 00:00:00",
"lt": "1980-01-01 00:00:00"
}
}
}
}
}
}
}
However, this query doesn't work
"query": {
"filtered": {
"filter": {
"bool" : {
"should": {
"terms": {
"headline":["aut"]
}
},
"must": {
"range": {
"date_at" : {
"gt": "1900-01-01 00:00:00",
"lt": "1980-01-01 00:00:00"
}
},
"term": {
"headline": "et"
}
}
}
}
}
}
The addition of the "term" clause inside the boolean "must" is causing a syntax error, all shards broken etc... The issue appears to be I want to use the same index twice inside two different bools specifically
headline MUST contain "foo"
headline SHOULD contain "bar"
Is it possible?

Have you tried this?
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"terms": {
"headline": [
"aut"
]
}
}
],
"must": [
{
"range": {
"date_at": {
"gt": "1900-01-01 00:00:00",
"lt": "1980-01-01 00:00:00"
}
}
},
{
"term": {
"headline": "et"
}
}
]
}
}
}
}
}
That would be the direct interpretation of what you're trying to do, but this is probably what you actually need:
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"range": {
"date_at": {
"gt": "1900-01-01 00:00:00",
"lt": "1980-01-01 00:00:00"
}
}
},
{
"term": {
"headline": "et"
}
}
]
}
}
}
}
}
Here is some code I used to play around with it:
http://sense.qbox.io/gist/ea16ff321397c2187ef503541019d52c564b7460

Related

need something like coalesce in elasticsearch

My current elasticsearch query is-
{
"must": [
{
"range": {
"firstClosedAt": {
"gte": 1667948400000,
"lte": 1668034800000
}
}
},
{
"term": {
"status": "CLOSED"
}
}
I want to modify it such that if "firstClosedAt" is null or not present then look for "closedAt".
Just like we have coalesce("firstClosedAt","closedAt") in sql
Help would be appreciated
There's no coalesce equivalent in ES, but you can do the query like below, which can read like: "either use firstClosedAt OR use closedAt if firstClosedAt does not exist":
{
"query": {
"bool": {
"filter": [
{
"term": {
"status": "CLOSED"
}
},
{
"bool": {
"minimum_should_match": 1,
"should": [
{
"range": {
"firstClosedAt": {
"gte": 1667948400000,
"lte": 1668034800000
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "firstClosedAt"
}
},
"filter": {
"range": {
"closedAt": {
"gte": 1667948400000,
"lte": 1668034800000
}
}
}
}
}
]
}
}
]
}
}
}
You could, however, create a much simpler query if you create another date field at indexing time which would either take the value of firstClosedAt or closedAt if firstClosedAt does not exist

How to get only one field instead of list in Elasticsearch

So, there I have request that return one or two fields depends on their existence in document. But I need to receive only one field (no matter which one). How can I do it?
{
"_source" : ["yearOfBirth", "fullBirthDate"],
"size": 1000,
"query": {
"bool": {
"must": [],
"filter": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"range": {
"yearOfBirth": {
"gte": "1900",
"lte": "2020"
}
}
},
{
"range": {
"fullBirthDate": {
"gte": "1900",
"lte": "2020"
}
}
}
]
}
}
]
}
}
}
}
}

Elastic search - handling the condition using must or must not query

We have a requirement if newId is there then we have to get the data less than todays date
and if newId field is not there in the data then we have to get the data till expiry date + 2Months.
I was trying below query but result has not come as expected.
{
"id":"234",
"startDate":"23/07/2020",
"endDate":"24/09/20202",
"newId":"2345"
},
{
"id":"234",
"startDate":"23/07/2020",
"endDate":"24/09/20202",
"newId":null
},
{
"id":"235",
"startDate":"23/07/2020",
"endDate":"24/06/2020",
"newId":"2345"
},
Query that I was trying
{
"query": {
"bool": {
"must": [
{
"match_all": {}
},
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"exists": {
"field": "newId"
}
},
{
"range": {
"endDate": {
"gte":"now/d"
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "newId"
}
},
{
"range": {
"endDate": {
"gte": "now-2M"
}
}
}
]
}
}
]
}
}
]
}
}
}
Expected result
{
"id":"234",
"startDate":"23/07/2020",
"endDate":"24/09/20202",
"newId":"2345"
},
{
"id":"234",
"startDate":"23/07/2020",
"endDate":"24/09/20202",
"newId":null
},
Great start! Your query is almost right, but you need a few more tweaks, namely to use should instead of must, because both sub-queries will never be true at the same time:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "newId"
}
},
{
"range": {
"endDate": {
"gte": "now/d"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"endDate": {
"gte": "now-2M"
}
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "newId"
}
}
]
}
}
]
}
}
]
}
}
}

ElasticSearch should/must clause not working as expected

Below is my elastic query
GET _search
{
"query": {
"bool": {
"must": {
"match": {
"marriages.marriage_year": "1630"
}
},
"should": {
"match": {
"first_name": {
"query": "mary",
"fuzziness": "2"
}
}
},
"must": {
"range": {
"marriages.marriage_year": {
"gt": "1620",
"lte": "1740"
}
}
}
}
}
}
It is returning data with marriages.marriage_year= "1630" with Mary as first_name as highest score.I also want to include marriages.marriage_year between 1620 - 1740 which are not shown in the results. It is showing data only for marriage_year 1630
That's because you have two bool/must clauses and the second one gets eliminated when the JSON query is parsed. Rewrite it like this instead and it will work:
{
"query": {
"bool": {
"must": [
{
"match": {
"marriages.marriage_year": "1630"
}
},
{
"range": {
"marriages.marriage_year": {
"gt": "1620",
"lte": "1740"
}
}
}
],
"should": {
"match": {
"first_name": {
"query": "mary",
"fuzziness": "2"
}
}
}
}
}
}
UPDATE
Then you need to do it differently and in the bool/must you need to have only the range query and move the match inside the bool/should section:
{
"query": {
"bool": {
"must": [
{
"range": {
"marriages.marriage_year": {
"gt": "1620",
"lte": "1740"
}
}
}
],
"should": [
{
"match": {
"first_name": {
"query": "mary",
"fuzziness": "2"
}
}
},
{
"match": {
"marriages.marriage_year": "1630"
}
}
]
}
}
}

How do I recreate an "or" query now that "missing" is deprecated?

I am upgrading to elasticsearch 5.2 and have the following query, which now fails because the "missing" filter is deprecated:
{
"query": {
"bool": {
"should": [
{
"missing": {
"field": "birthday"
}
},
{
"range": {
"birthday": {
"lte": "20131231"
}
}
}
]
}
}
}
So, I am looking for documents that are either missing the birthday field or have a birthday less than 12/31/2013. The suggested replacement for "missing" is to use "must_not". I get that but how do I now do the same "or" query I had going on before? I have:
{
"query": {
"bool": {
"should": {
"range": {
"birthday": {
"lte": "20131231"
}
}
},
"must_not": {
"exists": {
"field": "birthday"
}
}
}
}
}
You're on the right path and almost there:
{
"query": {
"bool": {
"should": [
{
"range": {
"birthday": {
"lte": "20131231"
}
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "birthday"
}
}
}
}
]
}
}
}

Resources