Elastic search sort with match word if it is exist - elasticsearch

I have the following document structure example:
{
'is_creator' : 1,
'is_verified_by_id' : 0,
'is_verified' : 0,
'country' : 'US'
}
currently i do have the following sorting filter
["is_creator" => "desc"],
["is_verified" => "desc"]
so it will sort the creator users first then the verified ones and etc..
Question:
How i can search the results with same sorting method but for selected country first then other countries, for example i want to apply the same sort but the country must be US then other countries, like this order:
- Creators from the same country (US).
- Creators from rest countries (other countries).
- Verified by Admin from same country (US)
- Verified by Admin rest countries (other countries).
- Verified by ID from same country (US)
- Verified by ID from rest countries (other countries)
- Not verified from same country (US)
- Not verified from rest countries (other countries)
i hope the question is understandable.
Thanks !

In elastic search you can use bool query to in combination with term query to search.
Below are the queries you asked:
- Creators from the same country (US).
Use must block of bool query to specify that the result docs must meet the specified condition
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "country": { "value": "US" } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Creators from rest countries (other countries)
Use must_not block of bool query to specify that the result docs must not meet the specified condition
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must_not": [
{ "term": { "country": { "value": "US" } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Verified by Admin from same country (US)
Add one more term for admin verification in must block
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "country": { "value": "US" } } },
{ "term": { "is_verified": { "value": 1 } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Verified by Admin rest countries (other countries).
Add is_verified to must block and country to must_not to get the only the verified docs for all countries other than the specified country
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "is_verified": { "value": 1 } } }
],
"must_not": [
{ "term": { "country": { "value": "US" } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Verified by ID from same country (US)
Add is_verified_by_id and country to the must block to get the only the verified by id docs for the specified country
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "country": { "value": "US" } } },
{ "term": { "is_verified_by_id": { "value": 1 } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Verified by ID from rest countries (other countries)
Add is_verified_by_id to must block and country to must_not to get the only the verified by id docs for all countries other than the specified country
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "is_verified_by_id": { "value": 1 } } }
],
"must_not": [
{ "term": { "country": { "value": "US" } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Not verified from same country (US)
Add is_verified to must_not block and country to must to get the non verified docs for the specified country
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must": [
{ "term": { "country": { "value": "US" } } }
],
"must_not": [
{ "term": { "is_verified": { "value": 1 } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}
- Not verified from rest countries (other countries)
Add is_verified and country to must_not block to get the non verified docs for the countries other than the specified one
GET <INDEX_NAME>/_search
{
"query": {
"bool": {
"must_not": [
{ "term": { "is_verified": { "value": 1 } } },
{ "term": { "country": { "value": "US" } } }
]
}
},
"sort": [
{ "is_creator": { "order": "desc" } },
{ "is_verified": { "order": "desc" } }
]
}

Related

How to return results from elasticsearch after a threshold match

I have two queries as follows:
The first query returns the count of all documents per domain.
The second query returns the count where a field is empty.
Later I filter it in my backend, such that, if for a domain the count of documents missing field value is more than a specific threshold then only consider them else ignore. Could these two queries be combined together, such that I could do the threshold comparison and then return the results.
The first query is as follows:
GET database/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"term": {
"source": {
"value": "Web"
}
}
}
]
}
},
"aggs": {
"domains": {
"terms": {
"field": "domain_id"
}
}
}
}
The second query just applies a should filter as follows:
GET mapachitl/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"term": {
"source": {
"value": "Web"
}
}
}
],
"should": [
{
"term": {
"address.city.keyword": {
"value": ""
}
}
},
{
"term": {
"address.zip.keyword": {
"value": ""
}
}
}
],
"minimum_should_match": 1
}
},
"aggs": {
"domains": {
"terms": {
"field": "domain_id"
}
}
}
}
Can I only return those domains where the ratio of documents missing city or zip code is more than 25%? I read about scripting but not sure how can I use it here.

Elasticsearch Last document of multiple term queries

I need to get the last document of each interface, I have played around with different queries but I can get the desired result, below is my las attempt.
Can you help me to get the last document of each interface where the field throughput exist?
Thanks
GET /interface-2021.11/_search
{
"query": {
"bool": {
"should": [
{
"term": {
"interface_name.keyword": {
"value": "Gi0/0/2 on (EXT-01)"
}
}
},
{
"term": {
"interface_name.keyword": {
"value": "Gi0/0/1 on (EXT-02)"
}
}
},
{
"term": {
"interface_name.keyword": {
"value": "Ethernet1/61 on (DC-01)"
}
}
},
{
"term": {
"interface_name.keyword": {
"value": "Ethernet1/17 on (DC-02)"
}
}
}
],
"minimum_should_match": 1,
"filter": [
{
"exists": {
"field": "throughput"
}
}
]
}
},
"aggs": {
"top_date": {
"top_hits": {
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
]
}
}
}
}
Good job, you're on the right path! You just need to aggregate by interface_name.keyword and get the top hit for each interface.
Here is the query that will work as you expect:
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"terms": {
"interface_name.keyword": [
"Gi0/0/2 on (EXT-01)",
"Gi0/0/1 on (EXT-02)",
"Ethernet1/61 on (DC-01)",
"Ethernet1/17 on (DC-02)"
]
}
},
{
"exists": {
"field": "throughput"
}
}
]
}
},
"aggs": {
"interfaces": {
"terms": {
"field": "interface_name.keyword"
},
"aggs": {
"top_date": {
"top_hits": {
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
]
}
}
}
}
}
}

Elasticsearch multiple fields OR query

Here is an example record that I have stored in ES:
"taskCurateStatus": true,
"taskMigrateStatus": true,
"verifiedFields": 7,
"taskId": "abcdef123",
"operatorEmail": "test#test.com"
Example Query I'm making via /_search:
{
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
],
"query": {
"bool": {
"must": [
{
"match": {
"msg.operator_email": "test#test.com"
}
}
{
"range": {
"#timestamp": {
"gte": "2017-03-05",
"lte": "2017-03-12"
}
}
}
]
}
},
"from": 0,
"size": 50
}
Basically I want to also filter by documents that have EITHER taskCurateStatus or taskMigrateStatus be true. Some messages have only one of them defined. I was thinking of using a should query but not sure how that would work with the match query. Any help would be appreciated. Thanks
you can add another boolean filter inside your must filter. This boolean filter can implemenet the should clause where you can compare the boolean flags with a should filter combining both the boolean check filters
{
"sort": [{
"#timestamp": {
"order": "desc"
}
}],
"query": {
"bool": {
"must": [{
"match": {
"msg.operator_email": "test#test.com"
}
}, {
"range": {
"#timestamp": {
"gte": "2017-03-05",
"lte": "2017-03-12"
}
}
}, {
"bool": {
"should": [{
"term": {
"taskCurateStatus": {
"value": true
}
}
}, {
"term": {
"taskMigrateStatus": {
"value": true
}
}
}]
}
}]
}
},
"from": 0,
"size": 50
}
Take a look at the above query and see if the helps
Thanks

Elasticsearch must_not filter not works with a big bunch of values

I have the next query that include some filters:
{
"from": 0,
"query": {
"function_score": {
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"idpais": [
115
]
}
},
{
"term": {
"tipo": [
1
]
}
}
],
"must_not": [
{
"term": {
"idregistro": [
5912471,
3433876,
9814443,
11703069,
6333176,
8288242,
9924922,
6677850,
11852501,
12530205,
4703469,
12776479,
12287659,
11823679,
12456304,
12777457,
10977614,
...
]
}
}
]
}
},
"query": {
"bool": {
"should": [
{
"match_phrase": {
"area": "Coordinator"
}
},
{
"match_phrase": {
"company": {
"boost": 5,
"query": "IBM"
}
}
},
{
"match_phrase": {
"topic": "IT and internet stuff"
}
},
{
"match_phrase": {
"institution": {
"boost": 5,
"query": "University of my city"
}
}
}
]
}
}
}
},
"script_score": {
"params": {
"idpais": 115,
"idprovincia": 0,
"relationships": []
},
"script_id": "ScoreUsuarios"
}
}
},
"size": 24,
"sort": [
{
"_script": {
"order": "desc",
"script_id": "SortUsuarios",
"type": "number"
}
}
]
}
The must_not filter has a big bunch of values to exclude (around 200 values), but it looks like elasticsearch ignores those values and it includes on the result set. If I try to set only a few values (10 to 20 values) then elasticsearch applies the must_not filter.
Exists some restriction a bout the amount of values in the filters? Exists some way to remove a big amount of results from the query?
terms query is used for passing a list of values not term query.You have to use it like below in your must filter.
{
"query": {
"terms": {
"field_name": [
"VALUE1",
"VALUE2"
]
}
}
}

Elasticsearch: multiple sorts for nested fields

have a situation where treatment has a price and hospital may or may not want to display it.
so there is a price field PLUS a lp_low_priority field.
value of lp_low_priority is 1(true) when price is not set(price is_null).
hospital doc is saved with its nested treatments.
when user searches for treatment he get list of hospitals with minimum price of the treatment.
now the sort works fine.
BUT i want the hospital with that treatment with the lp_low_priority = 1 to come at last.
Code to search is like
{
"sort": [
{
"treatments.lowest_price": {
"nested_filter": {
"term": {
"treatments.treatment_slug": "heart-surgery"
}
},
"mode": "avg",
"order": "asc"
}
},
{
"treatments.lp_low_priority": {
"order": "asc",
"nested_filter": {
"term": {
"treatments.treatment_slug": "heart-surgery"
}
},
"mode": "max"
}
}
],
"query": {
"filtered": {
"filter": [
{
"term": {
"treatments.treatment_slug": "heart-surgery"
}
},
{
"term": {
"treatments.status": "active"
}
},
{
"term": {
"treatments.treatment_status": "active"
}
},
{
"term": {
"hospital_status": "active"
}
},
{
"terms": {
"location.country": [
"India"
]
}
}
]
}
}
}
the result is way too weird.
if I only use
{
"sort": [
{
"treatments.lowest_price": {
"nested_filter": {
"term": {
"treatments.treatment_slug": "heart-surgery"
}
},
"mode": "avg",
"order": "asc"
}
}
The sorting is in order but then you see the lp_low_priority come first in order, which is OK(but not the requirement).
Can i even use more than one sorts for nested fields.

Resources