ElasticSearch - use two range queries to find documents that match either or both of the queries - elasticsearch

The index has fields discount_a and discount_b. I want to find documents where either discount_a is "gte": 10 OR discount_b is "gte": 15.
I want the query to find documents that match one or both criteria. I tried putting the range queries in the should, but this also returns documents that do not meet either criteria.
ElasticSearch version is 6.8.
Ideally I want to do something like this, except find documents that match either of the range queries, not necessarily both.
{
"query": {
"bool": {
"must": [
{
"match_all": {}
},
{
"range": {
"discount_a": {
"gte": 10
}
}
},
{
"range": {
"discount_b": {
"gte": 15
}
}
}
],
"filter": [],
"should": [],
"must_not": []
}
},
"from": 0,
"size": 500
}
Here's what I tried in the should
"should": [
{
"range": {
"discount_a": {
"gte": 10
}
}
},
{
"range": {
"discount_b": {
"gte": 15
}
}
}
]

{
"query": {
"bool": {
"should": [
{
"range": {
"discount_a": {
"gte": 10
}
}
},
{
"range": {
"discount_b": {
"gte": 15
}
}
}
]
},
"minimum_should_match": "1"
}
}

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

Compond query with Elasticsearch

I'm trying to perform a search with the intended criteria being (activationDate in range 1598889600 to 1602051579) or someFlag=true.
Below is the query I tried, but it does not yield any records with someFlag=true (even with a big size, e.g. 5000). My Elasticsearch does have a lot of records with someFlag=true.
There are about 3000 total documents and this query returns around 280 documents.
{
"query": {
"bool": {
"must": [
{
"range": {
"activationDate": {
"gte": 1598889600
}
}
},
{
"range": {
"activationDate": {
"lte": 1602051579
}
}
}
],
"should": {
"match": {
"someFlag": true
}
}
}
},
"from": 1,
"size": 1000
}
Am I missing something?
This should work:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"range": {
"activationDate": {
"gte": 1598889600,
"lte": 1602051579
}
}
},
{
"term": {
"someFlag": true
}
}
]
}
}
]
}
}
}
In theory this should do the same:
{
"query": {
"bool": {
"should": [
{
"range": {
"activationDate": {
"gte": 1598889600,
"lte": 1602051579
}
}
},
{
"term": {
"someFlag": true
}
}
]
}
}
}
However the first query I've given wraps bool clause within a filter context (so that it does not need to score and query becomes cacheable).
Your bool query might have not worked because you were using match query, not term. match is normally used for text search only.
Replace the must with an should and set minimum_should_match=1 as is is an OR query and you are fine if just one of the ceiterias is met by any record. Next reduce the two range criterias to just one, where you combine gte and lte.

Use of range in Elasticsearch query

Below is the elastic search query. I need to use both the range and missing in a query.How can I change the below query
{
"query": {
"bool": {
"must": [
{
"constant_score": {
"filter": {
"missing": {
"field": "url"
}
}
}
}
],
"should": []
}
},
"_source": [
"id",
"com_name",
"website",
"_foundation._rating"
]
}
I need to add range to the above query. Kindly help me add the below section to the above query
"range": {
"_foundation._rating": {
"gte": 1,
"lte": 4
}
I suspect that the query you need is the following, i.e. the url field must be missing and the _foundation._rating field must be between and 1 and 4 (inclusive):
{
"query": {
"bool": {
"must": [
{
"missing": {
"field": "url"
}
},
{
"range": {
"_foundation._rating": {
"gte": 1,
"lte": 4
}
}
}
]
}
},
"_source": [
"id",
"com_name",
"url",
"_foundation._rating"
]
}
Based on the version of your elastic search, if you are using 5.x, you must use exists inside a must_not clause.
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-query.html
Try the below query:
{
"query": {
"range": {
"bool": {
"must": [
{
"term": {
"_foundation._rating": {
"gte": 1,
"lte": 4
}
}
}
],
"must_not": {
"exists": {
"field": "url"
}
}
}
}
}
}

Elasticsearch bool must only when field exists in document

I want to filter my documents if the publish date is in the future, and i do this with
{
"size": 8,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [{
"range": {
"meta.publish_date.date": {
"lte": "now"
}
}
}]
}
}
}
},
"from": 0
}
My problem now is that it only finds the documents which have the field 'publish_date' and is in the past. But i also want to find all the documents which not have this field.
How do I make such a query?
Thanks in advance.
You can also include documents in the response which don't have the date field, like this:
{
"from": 0,
"size": 8,
"query": {
"filtered": {
"filter": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"range": {
"meta.publish_date.date": {
"lte": "now"
}
}
},
{
"missing": {
"field": "meta.publish_date.date"
}
}
]
}
}
}
}
}

Resources