How to do AND / OR in Filter Aggregation - elasticsearch

In https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-filter-aggregation.html we learn:
{
"aggs" : {
"t_shirts" : {
"filter" : { "term": { "type": "t-shirt" } }
}
}
}
The above code show how we can aggs for t-shirt, but how do we do:
{
"aggs" : {
"t_shirts_or_shorts" : {
"filter" : { "term": { "type": "t-shirt" } OR "term": { "type": "shorts" } }
}
}
}
and
{
"aggs" : {
"black_t_shirts" : {
"filter" : { "term": { "type": "t-shirt" } AND "term": { "color": "black" } }
}
}
}

You can use "must" and should clause in filter aggregation same as in query.
Query1:
{
"size": 0,
"aggs": {
"t_shirts": {
"filter": {
"bool": {
"should": [
{
"term": {
"type.keyword": "t-shirt"
}
},
{
"term": {
"type.keyword": "shorts"
}
}
]
}
}
}
}
}
Query2:
{
"size": 0,
"aggs": {
"t_shirts": {
"filter": {
"bool": {
"must": [
{
"term": {
"type.keyword": "t-shirt"
}
},
{
"term": {
"color.keyword": "black"
}
}
]
}
}
}
}
}

You can combine filter criteria using the bool tag, much like you can query clauses.
You can also check this: Multiple filters and an aggregate in elasticsearch

Related

ElasticSearch filter by nested boolean type fields

I need to query on multiple nested fields on boolean types.
Structure of mapping:
"mappings" : {
"properties" : {
"leaders" : {
"type" : "nested",
"properties" : {
"except_1" : {
"type" : "boolean"
},
"except_2" : {
"type" : "boolean"
},
"counter" : {
"type" : "integer"
}
}
}
}
}
I am trying to use query both except1 and except2 only to False.
Below my try, unfortunately it returns True and False for both fields and I cannot fix it.
"query": {
"nested": {
"path": "leaders",
"query": {
"bool": {
"must": [
{
"term": {
"leaders.except_1": False
}
},
{
"term": {
"leaders.except_2": False
}
}
]
}
}
}
}
What you're probably looking for is the inner_hits option -- showing only the matched nested subdocuments.
PUT leaders
{"mappings":{"properties":{"leaders":{"type":"nested","properties":{"except_1":{"type":"boolean"},"except_2":{"type":"boolean"},"counter":{"type":"integer"}}}}}}
POST leaders/_doc
{
"leaders": [
{
"except_1": true,
"except_2": false
},
{
"except_1": false,
"except_2": false
}
]
}
GET leaders/_search
{
"query": {
"nested": {
"path": "leaders",
"inner_hits": {},
"query": {
"bool": {
"must": [
{
"term": {
"leaders.except_1": false
}
},
{
"term": {
"leaders.except_2": false
}
}
]
}
}
}
}
}
then
GET leaders/_search
{
"query": {
"nested": {
"path": "leaders",
"inner_hits": {},
"query": {
"bool": {
"must": [
{
"term": {
"leaders.except_1": false
}
},
{
"term": {
"leaders.except_2": false
}
}
]
}
}
}
}
}
yielding
{
"hits":[
{
"_index":"leaders",
"_type":"_doc",
"_id":"u-he8HEBG_KW3EFn-gMz",
"_score":0.87546873,
"_source":{ <-- default behavior
"leaders":[
{
"except_1":true,
"except_2":false
},
{
"except_1":false,
"except_2":false
}
]
},
"inner_hits":{
"leaders":{
"hits":{
"total":{
"value":1,
"relation":"eq"
},
"max_score":0.87546873,
"hits":[ <------- only the matching nested subdocument
{
"_index":"leaders",
"_type":"_doc",
"_id":"u-he8HEBG_KW3EFn-gMz",
"_nested":{
"field":"leaders",
"offset":1
},
"_score":0.87546873,
"_source":{
"except_1":false,
"except_2":false
}
}
]
}
}
}
}
]
}
Furthermore, you can force the system to only return the inner_hits by saying "_source": "inner_hits" on the top-level of your search query.

Elasticsearch filter "should" results with geolocation params

How to filter results from wildcard query with geolocation? My query look like this
{
"query": {
"bool" : {
"should": [
{
"wildcard": {
"title": {
"value": "*football*"
}
}
},
{
"wildcard": {
"description": {
"value": "*football*"
}
}
}
],
"filter" : {
"geo_distance" : {
"distance" : "90km",
"geolocation" : "45.50, 40.10"
}
}
}
}
}
But query always return results by geo_distance, like to skip wildcard params. I want to return only results where distance is max 90km but which contains "football" in title or description...
All you need to do is to add minimum_should_match: 1 in your query:
{
"query": {
"bool" : {
"minimum_should_match": 1, <-- add this
"should": [
{
"wildcard": {
"title": {
"value": "*football*"
}
}
},
{
"wildcard": {
"description": {
"value": "*football*"
}
}
}
],
"filter" : {
"geo_distance" : {
"distance" : "90km",
"geolocation" : "45.50, 40.10"
}
}
}
}
}

Elasticsearch [bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]

I have some problem with the elasticsearch query.
when I use the query code it feedback the messages
[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME].
POST /_search
{
"query": {
"bool": {
"must": {
"match": {
"_index": "ntopng-2017.07.26"
}
},
"filter": {
"term": {
"IPV4_DST_ADDR": "192.168.0.1"
}
}
} ,
"aggs" : {
"IN_PKTS" : { "sum" : { "field" :"IN_PKTS" } },
"IN_BYTES" : {"sum" : { "field":"IN_BYTES"} } ,
"OUT_BYTES" : {"sum" : { "field":"OUT_BYTES"} },
"OUT_PKTS" : { "sum" : { "field" :"OUT_PKTS" } }
}
}
}
aggs is misplaced. Try this:
{
"query": {
"bool": {
"must": {
"match": {
"_index": "ntopng-2017.07.26"
}
},
"filter": {
"term": {
"IPV4_DST_ADDR": "192.168.0.1"
}
}
}
},
"aggs": {
"IN_PKTS": {
"sum": {
"field": "IN_PKTS"
}
},
"IN_BYTES": {
"sum": {
"field": "IN_BYTES"
}
},
"OUT_BYTES": {
"sum": {
"field": "OUT_BYTES"
}
},
"OUT_PKTS": {
"sum": {
"field": "OUT_PKTS"
}
}
}
}

Filtered bool vs Bool query : elasticsearch

I have two queries in ES. Both have different turnaround time on the same set of documents. Both are doing the same thing conceptually. I have few doubts
1- What is the difference between these two?
2- Which one is better to use?
3- If both are same why they are performing differently?
1. Filtered bool
{
"from": 0,
"size": 5,
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"called_party_address_number": "1987112602"
}
},
{
"term": {
"original_sender_address_number": "6870340319"
}
},
{
"range": {
"x_event_timestamp": {
"gte": "2016-07-01T00:00:00.000Z",
"lte": "2016-07-30T00:00:00.000Z"
}
}
}
]
}
}
}
},
"sort": [
{
"x_event_timestamp": {
"order": "desc",
"ignore_unmapped": true
}
}
]
}
2. Simple Bool
{
"query": {
"bool": {
"must": [
{
"term": {
"called_party_address_number": "1277478699"
}
},
{
"term": {
"original_sender_address_number": "8020564722"
}
},
{
"term": {
"cause_code": "573"
}
},
{
"range": {
"x_event_timestamp": {
"gt": "2016-07-13T13:51:03.749Z",
"lt": "2016-07-16T13:51:03.749Z"
}
}
}
]
}
},
"from": 0,
"size": 10,
"sort": [
{
"x_event_timestamp": {
"order": "desc",
"ignore_unmapped": true
}
}
]
}
Mapping:
{
"ccp": {
"mappings": {
"type1": {
"properties": {
"original_sender_address_number": {
"type": "string"
},
"called_party_address_number": {
"type": "string"
},
"cause_code": {
"type": "string"
},
"x_event_timestamp": {
"type": "date",
"format": "strict_date_optional_time||epoch_millis"
},
.
.
.
}
}
}
}
}
Update 1:
I tried bool/must query and bool/filter query on same set of data,but I found the strange behaviour
1-
bool/must query is able to search the desired document
{
"query": {
"bool": {
"must": [
{
"term": {
"called_party_address_number": "8701662243"
}
},
{
"term": {
"cause_code": "401"
}
}
]
}
}
}
2-
While bool/filter is not able to search the document. If I remove the second field condition it searches the same record with field2's value as 401.
{
"query": {
"bool": {
"filter": [
{
"term": {
"called_party_address_number": "8701662243"
}
},
{
"term": {
"cause_code": "401"
}
}
]
}
}
}
Update2:
Found a solution of suppressing scoring phase with bool/must query by wrapping it within "constant_score".
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"called_party_address_number": "1235235757"
}
},
{
"term": {
"cause_code": "304"
}
}
]
}
}
}
}
}
Record we are trying to match have "called_party_address_number": "1235235757" and "cause_code": "304".
The first one uses the old 1.x query/filter syntax (i.e. filtered queries have been deprecated in favor of bool/filter).
The second one uses the new 2.x syntax but not in a filter context (i.e. you're using bool/must instead of bool/filter). The query with 2.x syntax which is equivalent to your first query (i.e. which runs in a filter context without score calculation = faster) would be this one:
{
"query": {
"bool": {
"filter": [
{
"term": {
"called_party_address_number": "1277478699"
}
},
{
"term": {
"original_sender_address_number": "8020564722"
}
},
{
"term": {
"cause_code": "573"
}
},
{
"range": {
"x_event_timestamp": {
"gt": "2016-07-13T13:51:03.749Z",
"lt": "2016-07-16T13:51:03.749Z"
}
}
}
]
}
},
"from": 0,
"size": 10,
"sort": [
{
"x_event_timestamp": {
"order": "desc",
"ignore_unmapped": true
}
}
]
}

How to combine term filters with a missing filter in Elasticsearch?

We are using Elasticsearch 1.6 and I have a working three term query that I need to modify with a stand alone working missing filter. Here is the current code:
The original term query with three entries
GET ...
{
"query": {
"nested": {
"path": "MAIN_FIELD",
"query": {
"bool": {
"must": [
{
"term": {
"MAIN_FIELD.ID": 1234
}
},
{
"term": {
"MAIN_FIELD.OTHER_IND": "false"
}
},
{
"term": {
"MAIN_FIELD.INDICATOR": "Y"
}
}
]
}
}
}
}
}
The stand alone missing query:
GET ...
{
"query" : {
"filtered" : {
"filter" : {
"missing" : { "field" : "MAIN_FIELD.OTHER_IND" }
}
}
}
}
How do I change the term query from the first query:
"term": {
"MAIN_FIELD.OTHER_IND": "false"
}
to use a missing filter?
I think what you want is below:
{
"query": {
"nested": {
"path": "MAIN_FIELD",
"query": {
"bool": {
"must": [
{
"term": {
"MAIN_FIELD.ID": 1234
}
},
{
"filtered": {
"filter": {
"missing": {
"field": "MAIN_FIELD.OTHER_IND"
}
}
}
},
{
"term": {
"MAIN_FIELD.INDICATOR": "Y"
}
}
]
}
}
}
}
}

Resources