range between two dates in elastic Search - elasticsearch

i have a question with filter, range and or with elastic search.
I have de document in elasticSearch with
{
startDate : myDate
endDate : onOtherDateOr Nothing
}
I Want to search for a range where now is after startDate, or Between startDate and endDate if endDate is defined. How can i do that ?

You can do it like this with two bool/should filters containing two nested bool/must filters:
curl -XPOST localhost:9200/_search -d '{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"bool": {
"must": [ <--- if endDate exists, check both bounds
{
"exists": {
"field": "endDate"
}
},
{
"range": {
"startDate": {
"lte": "now"
}
}
},
{
"range": {
"endDate": {
"gte": "now"
}
}
}
]
}
},
{
"bool": {
"must": [ <--- if endDate missing, only check startDate
{
"missing": {
"field": "endDate"
}
},
{
"range": {
"startDate": {
"lte": "now"
}
}
}
]
}
}
]
}
}
}
}
}'

I find below query as best approach:
{
"query": {
"range": {
"order.dateCreated": {
"dateFrom": "2011-01-24",
"dateTo": "2011-01-24"
}
}
}
}

try the next query, at least it works for me.`
"query": {
"range": {
"date_ field ": { # this field_name should be the field where your date range
resides.
"gte": startDate,
"lte": endDate,
"boost": 2.0
}
}
}`

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

In elastic how can I add sort to my query so that it returns the results in a sorted order

"query": {
"bool": {
"must":[
{
"range": {
"Date": {
"gte": firstDate,
"lte": lastDate
}
}
},
]
}
}
Above is my query how can I add the sort feature so that I get the values returned sorted as right now they are not being returned sorted
You can use Sort search to sort the results by one or more fields.
Example:
{
"query": {
"bool": {
"must": [
{
"range": {
"Date": {
"gte": "firstDate",
"lte": "lastDate"
}
}
}
]
}
},
"sort": [
{
"firstDate": {
"order": "desc"
}
}
]
}
You could insert a sort clause
{
"sort": [
{
"Date": {
"format": "strict_date_optional_time_nanos",// From https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html
"order" : "desc"
}
}
],
"query": {
"bool": {
"must": [
{
"range": {
"Date": {
"gte": firstDate,
"lte": lastDate
}
}
}
]
}
}
}

Elasticsearch query greater than date

I create an index and it save two date (D1, D2) for something, after that I want to query this monent is it between D1 and D2, so I query :
startdate <= "2019-08-22T03:55:47.165Z" AND endate>= "2019-08-22T03:55:47.165Z"
It successful return the data as I want, so I try to do the same things in Dev tools again with:
GET i_want_get_date/_search
{
"query":{
"query_string":{
"query":"startdate<= \"2019-08-22T03:55:47.165Z\" AND enddate>= \"2019-08-22T03:55:47.165Z\""
}
}
}
The problem is:
it cannot search any result back, the query cannot compare the date using this method
Any suggestion? Thanks!
============================================================
Thanks Val answer the question, I using a very slimier query to do the same function, I change a little bit query syntax to make it works:
GET i_want_get_date/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"startdate":{
"lte":"2019-08-22T03:55:47.165Z"
}
}
},
{
"range": {
"enddate":{
"gte":"2019-08-22T03:55:47.165Z"
}
}
}
]
}
}
}
I suggest to use two range queries instead
GET i_want_get_date/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"lte": {
"startdate": "2019-08-22T03:55:47.165Z"
}
}
},
{
"range": {
"gte": {
"enddate": "2019-08-22T03:55:47.165Z"
}
}
}
]
}
}
}
This is the query that worked for me to select dates after based on a specific field:
{
"query": {
"bool": {
"filter": [
{
"range": {
"_kuzzle_info.createdAt": {
"gte": "2023-01-09T13:29:27.537+00:00"
}
}
}
]
}
}
}
_kuzzle_info.createdAt is the field with the date
there is a syntax error in your answer, the elastic fields should come before the gte or lte
{
"range": {
"**startdate**": {
"**lte**": "2019-08-22T03:55:47.165Z"
}
}
}

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

Aggregate Date Range filtered values in elastic search

I need to filter a group of values based on date (added field here) and then group it by device_id. So I am using the following thing :
{
"aggs":{
"dates_between":{
"filter": {
"range" : {
"added" : {
"gte": "2014-07-01 00:00:00",
"lte" :"2014-08-01 00:00:00"
}
}
},
"aggs": {
"group_by_device_id": {
"terms": {
"field": "device_id"
}
}
}
}
}
}
This is giving me an error "Failed to parse source" when executing the query. This is the right way of doing it ?
If I execute the date aggregation only it is showing values which are not in the specified date range
It is the other way around dates_between is a nested aggregation of group_by_device_id
"aggs": {
"group_by_device_id": {
"terms": {
"field": "device_id"
},
"aggs": {
"dates_between": {
"filter": {
"range": {
"added": {
"gte": "2014-07-01 00:00:00",
"lte": "2014-08-01 00:00:00"
}
}
}
}
}
}
}
You could also move the filter into the the query:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"range": {
"added": {
"gte": "2014-07-01 00:00:00",
"lte": "2014-08-01 00:00:00"
}
}
}
}
},
"aggs": {
"group_by_device_id": {
"terms": {
"field": "device_id"
}
}
}
}

Resources