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
Related
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"
}
}
}
]
}
}
]
}
}
}
}
}
I have this following query with elastic:
{
"query": {
"bool": {
"filter": [{
"terms": {
"participants.group": ["group1","group2"]
}
}, {
"range": {
"recordDate": {
"gte": "2020-05-14 00:00:00.000",
"lte": "2020-07-22 20:30:56.566"
}
}
}]
}
}
}
Currently, this finds records with participants with group "group1" and "group2".
How to change the query so it finds records with participants from "group1" or "group2?
Is it possible to do it without changing the structure of the query?
I'm assuming that the field participants.group is of keyword type and not text type.
Assuming that, the query you have roughly translates to (group1) or (group2) or (group1 and group2).
All you need to do is modify the query as below and add a must_not clause like below:
POST my_filter_index/_search
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"range": {
"recordDate": {
"gte": "2020-05-14 00:00:00.000",
"lte": "2020-07-22 20:30:56.566"
}
}
}
],
"should": [
{
"terms": {
"participants.group": ["group1", "group2"]
}
}
]
}
}
],
"must_not": [
{
"bool": {
"must": [
{
"term": {
"participants.group": "group1"
}
},
{
"term": {
"participants.group": "group2"
}
}
]
}
}
]
}
}
}
Let me know if that works!
I need to search my index based on a timestamp.
The documents have these field combinations:
start_time and end_time
or
just start_time (no end_time field)
Pseudo query: .
For a given timestamp, I wish to return all documents where an id matches, and also:
timestamp >= start_time && timestamp < end_time
but if there is no end_time field, then the query needs to be this:
(not exists end_time) && (timestamp > start_time)
Elastic query .
This is where I am going mad. I can't get an elastic query equivilent to that pseudo query above. Perhaps I am approaching it the wrong way (entirely possible). Here is what I have:
{
"query": {
"bool": {
"must": [
{
"term": {
"id_s": "SomeIdValue"
}
},
{
"bool": {
"should": [
{
"must": [
{
"must_not": [
{
"exists": {
"field": "end_time_dt"
}
}
]
},
{
"range": {
"start_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
}
]
},
{
"filter": [
{
"range": {
"start_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
},
{
"range": {
"end_time_dt": {
"gte": "2019-07-12T03:20:22"
}
}
}
]
}
]
}
}
]
}
}
}
But this gives me [must] query malformed, no start_object after query name
How do I construct this query? Am I on the right track?
thanks in advance!
Your query is syntactically wrong. The correct query would be:
{
"query": {
"bool": {
"filter": [
{
"term": {
"id_s": "SomeIdValue"
}
},
{
"bool": {
"should": [
{
"bool": {
"must_not": [
{
"exists": {
"field": "end_time_dt"
}
}
],
"must": [
{
"range": {
"start_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"start_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
},
{
"range": {
"end_time_dt": {
"gte": "2019-07-12T03:20:22"
}
}
}
]
}
}
]
}
}
]
}
}
}
There is a slight mistake in the logic. Ideally, comparison should be like this gte start_time_dt and lte end_time_dt. You did other way round so that translates to timestamp <= start_time && timestamp > end_time.
The correct query is
{
"query": {
"bool": {
"filter": [
{
"term": {
"id_s": "SomeIdValue"
}
},
{
"bool": {
"should": [
{
"bool": {
"must_not": [
{
"exists": {
"field": "end_time_dt"
}
}
],
"must": [
{
"range": {
"start_time_dt": {
"gte": "2019-07-12T03:20:22"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"start_time_dt": {
"gte": "2019-07-12T03:20:22"
}
}
},
{
"range": {
"end_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
}
]
}
}
]
}
}
]
}
}
}
Hope this helps!!
I believe this block should be must not should as mentioned in the answer. The reason I say is both those conditions: must ( not exists AND range ) is what the OP intention I believe
{
"bool": {
"must": [ <====== mentioned it as should
{
"bool": {
"must_not": [
{
"exists": {
"field": "end_time_dt"
}
}
],
"must": [
{
"range": {
"start_time_dt": {
"lte": "2019-07-12T03:20:22"
}
}
}
]
}
},
How am I able to put both of these queries together, as you can see that query one is bringing back all the date from today and the second query is bringing back data for all users that has the name test in it.
So I want to bring back all of the data for data with the name that has test in it.
Could someone show me how this is done please?
Query one:
{
"_source":["VT"],
"query": {
"range": {
"VT": {
"gte": "now/d",
"lt": "now/d+13h"
}
}}
}
Query two:
from elasticsearch import Elasticsearch
es = Elasticsearch(["9200"])
res = es.search(index="search", body=
{
"_source": ["DTDT", "TRDT"],
"query": {
"bool": {
"should": [
{"wildcard": {"N": "TEST*"}}
]
}
}
}, size=10
)
for doc in res['hits']['hits']:
print(doc)
You can use a bool query with two must clauses, like this:
{
"_source": ["DTDT", "TRDT", "VT"],
"query": {
"bool": {
"must": [
{
"range": {
"VT": {
"gte": "now/d",
"lt": "now/d+13h"
}
}
},
{
"wildcard": {
"N": "TEST*"
}
}
]
}
}
}
Check out the docs for the bool query.
This will help you:
POST _search
{
"query": {
"bool": {
"must": [
{
"range": {
"VT": {
"gte": "now/d",
"lt": "now/d+13h"
}
}
},
{
"match": {
"N": {
"query": "TEST",
"operator": "and"
}
}
}]
}
}
}
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"
}
}
}
}
}
}