Geo, Date, and string matching elasticsearch query - elasticsearch

I have an elasticsearch index called tweets,
I'm trying to filter these tweets by geo_distance, date, and optional string that might be passed. How should this query be like to meet my requirements
"query":{
"bool": {
"must": [
{
"term": {
"text": "ew"
}
},
{
"range": {
"date": {
"gte": "2009-05-31T02:30:45",
"lt": "now"
}
}
},
{
"filter": {
"geo_distance": {
"distance": "12km",
"pin.location": [-70, 40]
}
}
}
]
}
}
Thanks in advance

You can use the combination of filter and should clause, to achieve your required result.
filter is used similar to logical AND operator, where the score of the query is ignored, and should is similar to logical OR operator.
Try out this below query:
{
"query": {
"bool": {
"filter": [
{
"range": {
"date": {
"gte": "2009-05-31T02:30:45",
"lt": "now"
}
}
},
{
"geo_distance": {
"distance": "12km",
"pin.location": [
-70,
40
]
}
}
],
"should": {
"bool": {
"filter": {
"term": {
"text": "ew"
}
}
}
}
}
}
}

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 combine Boolean AND with Boolean OR in Elasticsearch query?

Query: Get employee name "Mahesh" whose id is "200" and joining datetime is in a given date range and his epf status must be either 'NOK' or 'WRN'. (Possible values of epf_status are {OK,NOK,WRN,CANCELLED}.
I have written the following query, that matches epf_status also with OK, CANCELLED, but it must only match when epf_status is either 'NOK' or 'WRN'. What else do I need to change to make it work, as required?
GET myindex01/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"empname": { "query": "Mahesh", "operator": "AND" }
}
},
{
"match": {
"empid": { "query": "200", "operator": "AND" }
}
},
{
"range": {
"joining_datetime": {
"gte": "2020-01-01T00:00:00",
"lte": "2022-06-24T23:59:59"
}
}
}
],
"should": [
{ "match": { "epf_status": "NOK" } },
{ "match": { "epf_status": "WRN" } }
]
}
}
}
SAMPLE DATA:
{"Mahesh","200","2022-04-01","OK"}
{"Mahesh","200","2022-04-01","NOK"}
{"Mahesh","200","2022-04-01","WRN"}
{"Mahesh","200","2022-04-01","CANCELLED"}
REQUIRED OUTPUT:
{"Mahesh","200","2022-04-01","NOK"}
{"Mahesh","200","2022-04-01","WRN"}
Tldr;
You could be using the terms query for that I believe.
Returns documents that contain one or more exact terms in a provided field.
To solve
GET myindex01/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"empname": { "query": "Mahesh", "operator": "AND" }
}
},
{
"match": {
"empid": { "query": "200", "operator": "AND" }
}
},
{
"range": {
"joining_datetime": {
"gte": "2020-01-01T00:00:00",
"lte": "2022-06-24T23:59:59"
}
}
}
],
"should": [
{ "terms": { "epf_status": ["NOK", "WRN"] } }
]
}
}
}

With Elasticsearch, how to use an OR instead of AND within filter->terms query?

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!

Putting two queries together

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

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

Resources