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

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

Related

how to get value only from Elasticsearch sum aggregation query?

I'm using this query
POST /stats/_search?filter_path=aggregations.views.value
{
"aggs": {
"views": {
"sum": {
"field": "viewCount"
}
}
},
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"timestamp": {"gte":"now-2d"}
}
}
]
}
}
}
and it gives the result
{
"aggregations" : {
"views" : {
"value" : 49198.0
}
}
}
I'm looking to only get "49189.0" or the least amount of info possible, maybe "{value: 49198.0}"

How to do AND / OR in Filter Aggregation

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

Elasticsearch 5 | filter nested object and nested aggregation count

elasticsearch 5.2
I want to filter my items by the nested object state.id = 101 and an aggregation count for all the items by state.id. There are items with the state ids 101, 102 and 103.
The aggregation count is now limited to state.id 101. I want the only get the items with state.id = 101 and the aggregation count for all state ids.
How can i do this?
GET index/items/_search
{
"query": {
"nested" : {
"path" : "state",
"query": {
"bool": {
"filter": {
"term": { "state.id": 101 }
}
}
}
}
},
"aggs" : {
"state" : {
"nested" : {
"path" : "state"
},
"aggs" : {
"count" : { "terms" : { "field" : "state.id" } }
}
}
}
}
You need to use post_filter instead of query: (Oh and use POST instead of GET when sending a payload)
POST index/items/_search
{
"post_filter": { <--- change this
"nested": {
"path": "state",
"query": {
"bool": {
"filter": {
"term": {
"state.id": 101
}
}
}
}
}
},
"aggs": {
"state": {
"nested": {
"path": "state"
},
"aggs": {
"count": {
"terms": {
"field": "state.id"
}
}
}
}
}
}
If you want to further narrow the nested aggregation, you can also add a filter:
POST index/items/_search
{
"post_filter": {
"nested": {
"path": "state",
"query": {
"bool": {
"filter": {
"term": {
"state.id": 101
}
}
}
}
}
},
"aggs": {
"narrow": {
"filter": {
"nested": {
"path": "state",
"query": {
"bool": {
"filter": {
"term": {
"state.id": 101
}
}
}
}
}
},
"aggs": {
"state": {
"nested": {
"path": "state"
},
"aggs": {
"count": {
"terms": {
"field": "state.id"
}
}
}
}
}
}
}
}

Selecting documents with a specific field is set to NULL in Elasticsearch

Someone please help me to add expires_at IS NULL to ES query below. I looked into Dealing with Null Values section for missing filter but the way I used it (shown at the bottom) causes not expired documents not appearing in result so obviously I'm doing something wrong here.
Note: I don't want to use or query because it is deprecated in 2.0.0-beta1.
QUERY
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"term": {
"order_id": "123"
}
},
{
"term": {
"is_active": 1
}
},
{
"range": {
"expires_at": {
"gt": "2016-07-01T00:00:00+0000"
}
}
}
]
}
}
}
}
}
This is what I'm aiming at:
SELECT * FROM orders
WHERE
order_id = '123' AND
is_active = '1' AND
(expires_at > '2016-07-01T00:00:00+0000' OR expires_at IS NULL)
This is what I did, but un-expired documents won't show up in this case so this is wrong.
{
"query": {
"filtered": {
"filter": {
"missing": {
"field": "expires_at"
}
},
"query": {
"bool": {
"must": [
......
......
]
}
}
}
}
}
My ES version:
{
"status" : 200,
"name" : "Fan Boy",
"version" : {
"number" : "1.3.4",
"build_hash" : "a70f3ccb52200f8f2c87e9c370c6597448eb3e45",
"build_timestamp" : "2014-09-30T09:07:17Z",
"build_snapshot" : false,
"lucene_version" : "4.9"
},
"tagline" : "You Know, for Search"
}
This should do it:
{
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"term": {
"order_id": "123"
}
},
{
"term": {
"is_active": 1
}
},
{
"bool": {
"should": [
{
"range": {
"expires_at": {
"gt": "20160101000000"
}
}
},
{
"filtered": {
"filter": {
"missing": {
"field": "expires_at"
}
}
}
}
]
}
}
]
}
}
}
}
}

Elasticsearch - Aggregate a script field

I'm trying to create a script field that will calculate a time difference between two timestamps and then aggregate an avg on that script field.
I first tried:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"exists": {
"field": "time.new_time"
}
},
{
"exists": {
"field": "time.first_alert_time"
}
}
]
}
}
},
"script_fields": {
"timedifference": {
"script": "doc['time.new_time'].value - doc['time.first_alert_time'].value"
}
},
"aggs": {
"avg_timedifference": {
"avg": {
"field" : "timedifference"
}
}
}
}
Which resulted in null value under the aggregated avg avg_timedifference.
Then I tried:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"exists": {
"field": "time.new_time"
}
},
{
"exists": {
"field": "time.first_alert_time"
}
}
]
}
}
},
"script_fields": {
"timedifference": {
"script": "doc['time.new_time'].value - doc['time.first_alert_time'].value"
}
},
"aggs": {
"avg_timedifference": {
"avg": {
"script" : "doc['timedifference'].value"
}
}
}
}
Which generated an error message saying: "No field found for [timedifference] in mapping"
How about simply moving the script to the aggregation?
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"and": [
{
"exists": {
"field": "time.new_time"
}
},
{
"exists": {
"field": "time.first_alert_time"
}
}
]
}
}
},
"aggs": {
"avg_timedifference": {
"avg": {
"script" : "Math.ceil(doc['time.new_time'].value - doc['time.first_alert_time'].value)"
}
}
}
}

Resources