Filtered Query in Elastic Search - elasticsearch

Filtered Query query not working in elastic search. It gives a error Query Parsing exception with filter malformed, no field after start_object
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [],
"should": [
{
"_expires": null
},
{
"_expires": {
"gte": 1433947304884
}
}
],
"must_not": [
{
"term": {
"age": 19
}
}
]
}
}
}
},
"size": 10,
"from": 0
}
Can somebody help me with this?

Your shoulds should be actually using a filter. For yours you have "_expires": null. This is not a filter.
For example, try:
{
"missing": {
"field": "_expires"
}
},
{
"range": {
"_expires": {
"gte": 1433947304884
}
}
}

Related

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!

Find distinct/unique people without a birthday or have a birthday earlier than 3/1/1963

We have some employees and needed to find those we haven't entered their birthday or are born before 3/1/1963:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must_not": [{ "exists": { "field": "birthday" } }]
}
},
{
"bool": {
"filter": [{ "range": {"birthday": { "lte": 19630301 }} }]
}
}
]
}
}
}
We now need to get distinct names...we only want 1 Jason or 1 Susan, etc. How do we apply a distinct filter to the "name" field while still filtering for the birthday as above? I've tried:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must_not": [
{
"exists": {
"field": "birthday"
}
}
]
}
},
{
"bool": {
"filter": [
{
"range": {
"birthday": {
"lte": 19630301
}
}
}
]
}
}
]
}
},
"aggs": {
"uniq_gender": {
"terms": {
"field": "name"
}
}
},
"from": 0,
"size": 25
}
but just get results with duplicate Jasons and Susans. At the bottom it will show me that there are 10 Susans and 12 Jasons. Not sure how to get unique ones.
EDIT:
My mapping is very simple. The name field doesn't need to be keyword...can be text or anything else as it is just a field that just gets returned in the query.
{
"mappings": {
"birthdays": {
"properties": {
"name": {
"type": "keyword"
},
"birthday": {
"type": "date",
"format": "basic_date"
}
}
}
}
}
Without knowing your mapping, I'm guessing that your field name is not analyzed and able to be used on terms aggregation properly.
I suggest you, use filtered aggregation:
{
"aggs": {
"filtered_employes": {
"filter": {
"bool": {
"must": [
{
"bool": {
"must_not": [
{
"exists": {
"field": "birthday"
}
}
]
}
},
{
"range": {
"birthday": {
"lte": 19630301
}
}
}
]
}
},
"aggs": {
"filtered_employes_by_name": {
"terms": {
"field": "name"
}
}
}
}
}
}
In other hand your query is not correct your applying a should bool filter. Change it by must and the aggregation will return only results from employes with (missing birthday) and (born before date).

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: execute a filter on nested document only if it exists

I am using ES 2.3 and have a query in which filter section looks as follows:
"filter": {
"query": {
"bool": {
"must": [
{
"nested": {
"path": "employees",
"query": {
"bool": {
"must": [
{
"range": {
"employees.max_age": {
"lte": 50
}
}
},
{
"range": {
"employees.min_age": {
"gte": 20
}
}
}
]
}
}
}
},
{
"exists": {
"field": "employees"
}
},
{
#....other filter here based on root document, not on nested employee document
}
]
}
}
}
}
I have a filter, where I check some conditions in the nested document "employees" in a bigger document called company, But I want to run this filter, only if "employees" object exists, as some of the document may not have that nested document at all. So I added , {"exists": {"field": "employees"}}
but this doesn't seem to work. Any idea what change I should make to get it work?
You can do it like this. However, if documents don't have the employees field, they will not be picked up anyway, so I'm not sure why you want/need that exists query in the first place.
{
"filter": {
"query": {
"bool": {
"must": [
{
"nested": {
"path": "employees",
"query": {
"exists": {
"field": "employees"
}
}
}
},
{
"nested": {
"path": "employees",
"query": {
"bool": {
"must": [
{
"range": {
"employees.max_age": {
"lte": 50
}
}
},
{
"range": {
"employees.min_age": {
"gte": 20
}
}
}
]
}
}
}
}
]
}
}
}
}

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