Elasticsearch missing aggs - elasticsearch

I am doing an Elasticsearch query and having problems with the aggs going missing.
If I do the query below I get the aggs back without issue:
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "*wet*",
"fields": [
"Name",
"Summary",
"Description",
"Location",
"Features",
"TypeName",
"CategoryName"
]
},
"filter": {
"term": {
"TypeID": "13"
}
}
}
}
},
"aggs": {
"type": {
"terms": {
"field": "TypeID"
}
},
"category": {
"terms": {
"field": "CategoryID"
}
},
"max_price": {
"max": {
"field": "Price"
}
},
"min_price": {
"min": {
"field": "Price"
}
},
"filter-type": {
"term": {
"TypeID": "13"
}
}
},
"from": 0,
"size": 50,
"sort": {
"_score": {
"order": "desc"
}
},
"explain": false
}
However, as soon as I add a filter, the aggs are no longer returned. I can't see what I am doing wrong so any help would be really appreciated.
The one that doesn't return aggs looks like this:
{
"query": {
"filtered": {
"query": {
"query_string": {
"query": "*wet*",
"fields": [
"Name",
"Summary",
"Description",
"Location",
"Features",
"TypeName",
"CategoryName"
]
},
"filter": {
"term": {
"TypeID": "13"
}
}
}
}
},
"aggs": {
"type": {
"terms": {
"field": "TypeID"
}
},
"category": {
"terms": {
"field": "CategoryID"
}
},
"max_price": {
"max": {
"field": "Price"
}
},
"min_price": {
"min": {
"field": "Price"
}
},
"filter-type": {
"term": {
"TypeID": "13"
}
}
},
"from": 0,
"size": 50,
"sort": {
"_score": {
"order": "desc"
}
},
"explain": false
}

This is the correct syntax for filters aggregation. You have to wrap all you aggregation inside filter like this
{
"size": 0,
"query": {
"filtered": {
"query": {
"query_string": {
"query": "*wet*",
"fields": [
"Name",
"Summary",
"Description",
"Location",
"Features",
"TypeName",
"CategoryName"
]
}
},
"filter": {
"term": {
"TypeID": "13"
}
}
}
},
"aggs": {
"filter-type": {
"filter": {
"term": {
"TypeID": "13"
}
},
"aggs": {
"type": {
"terms": {
"field": "TypeID"
}
},
"category": {
"terms": {
"field": "CategoryID"
}
},
"max_price": {
"max": {
"field": "Price"
}
},
"min_price": {
"min": {
"field": "Price"
}
}
}
}
}
}
Also in this case filter in aggs is redundant as you are already using the same filter in your query.

Related

FIlter is not being applied to aggregation

I'm trying to get the billing of a product selled by a specific user, but it seems that the query is not being applied to the sum aggregation.
Could someone help me, please?
{
"query": {
"bool": {
"filter": [
{ "term": { "seller": 1 } },
{"term": { "product": 2 } }
]
}
},
"size": 0,
"aggs": {
"product": {
"terms": {
"field": "product"
},
"aggregations": {
"billing": {
"sum": {
"field": "price"
}
},
"aggregation": {
"bucket_sort": {
"sort": [
{
"billing": {
"order": "desc"
}
}
]
}
}
}
}
}
}
Try nesting your existing aggregations within another terms aggregation on "seller".
{
"query": {
"bool": {
"filter": [
{
"term": {
"seller": 1
}
},
{
"term": {
"product": 2
}
}
]
}
},
"size": 0,
"aggs": {
"seller": {
"terms": {
"field": "seller",
"size": 1
},
"aggs": {
"product": {
"terms": {
"field": "product",
"size": 1
},
"aggregations": {
"billing": {
"sum": {
"field": "price"
}
},
"aggregation": {
"bucket_sort": {
"sort": [
{
"billing": {
"order": "desc"
}
}
]
}
}
}
}
}
}
}
}

Elastic Search doesn't respect size when using aggregations

I am new to Elastic Search so please forgive me if the answer is obvious.
I have modified a query to use aggs to show 'distinct' results. However, after adding the aggs the size doesn't seem to work anymore - it always returns 10 results no matter what I set size to.
Would anyone know how I could use both aggs and size together?
My query is:
{
"size": "15",
"from": "0",
"query": {
"bool": {
"filter": [
{
"term": {
"category": "Cars"
}
},
{
"term": {
"location": "Sydney"
}
},
{
"term": {
"status": true
}
}
]
}
},
"sort": [
{
"_score": "desc"
},
{
"brand": "asc"
}
],
"aggs": {
"brand": {
"terms": {
"field": "brand",
"order": {
"price": "asc"
}
},
"aggs": {
"brand": {
"top_hits": {
"size": 1,
"sort": [
{
"price": {
"order": "asc"
}
}
]
}
},
"price": {
"min": {
"field": "price"
}
}
}
}
}
}
The size parameter you have mentioned before the query, is used to set the size for the query hits, and will not affect the aggregations bucket size.
Use the size parameter inside the parent aggregation just like you have mentioned in the sub-aggregation as "size":1
The modified query to get top 10 aggs is :
{
"size": "15",
"from": "0",
"query": {
"bool": {
"filter": [
{
"term": {
"category": "Cars"
}
},
{
"term": {
"location": "Sydney"
}
},
{
"term": {
"status": true
}
}
]
}
},
"sort": [
{
"_score": "desc"
},
{
"brand": "asc"
}
],
"aggs": {
"brand": {
"terms": {
"field": "brand",
"size": 10,
"order": {
"price": "asc"
}
},
"aggs": {
"brand": {
"top_hits": {
"size": 1,
"sort": [
{
"price": {
"order": "asc"
}
}
]
}
},
"price": {
"min": {
"field": "price"
}
}
}
}
}
}
Hope this helps.

Elasticsearch Aggregation on Aggregation or multiple aggregation

{
"aggs": {
"by_countryCode": {
"terms": {
"field":"countryCode.keyword",
"size": 100
},
"aggs": {
"views": {"sum": {"field": "views"}},
"shares": {"sum": {"field": "shares"}}
}
}
},
"query": {
"bool": {
"must": [
{ "match": { "userId": 1 } },
{ "match": { "artistId": 1001 }},
{ "range": {
"date" : {
"gte" : "20170310",
"lte" : "20170312"
}
}
}
]
}
}
}
This will return the matched items and also give me the aggregation results too. The aggregation is the sum of the views and shares group by the country code.
But I want another sum aggregation. I want the "total sum" and "total shares" too, how could I do that?
Thanks!
Adding the two additional aggregations at the top most level should do it:
{
"aggs": {
"by_countryCode": {
"terms": {
"field":"countryCode.keyword",
"size": 100
},
"aggs": {
"views": {"sum": {"field": "views"}},
"shares": {"sum": {"field": "shares"}}
}
},
"total_views": {
{"sum": {"field": "views"}}
},
"total_shares": {
{"sum": {"field": "shares"}}
},
"query": {
"bool": {
"must": [
{ "match": { "userId": 1 } },
{ "match": { "artistId": 1001 }},
{ "range": {
"date" : {
"gte" : "20170310",
"lte" : "20170312"
}
}
}
]
}
}
}
{
"aggs": {
"by_countryCode": {
"terms": {
"field":"countryCode.keyword",
"size": 100
},
"aggs": {
"views": {"sum": {"field": "views"}},
"shares": {"sum": {"field": "shares"}}
}
},
"total_views": {
"sum": {"field": "views"}
},
"total_shares": {
"sum": {"field": "shares"}
}
},
"query": {
"bool": {
"must": [
{ "match": { "userId": 1 } },
{ "match": { "artistId": 1001 }},
{ "range": {
"date" : {
"gte" : "20170310",
"lte" : "20170312"
}
}
}
]
}
}
}
Thanks, Roman!
With the help of your codes, I made some small changes. It works!

Elasticsearch summing buckets

I have the following request which will return the count of all documents with a status of either "Accepted","Released" or closed.
{
"size": 0,
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "*",
"analyze_wildcard": true
}
}
],
"must_not": []
}
},
"aggs": {
"slices": {
"terms": {
"field": "status.raw",
"include": {
"pattern": "Accepted|Released|Closed"
}
}
}
}
}
In my case the response is:
"buckets": [
{
"key": "Closed",
"doc_count": 2216
},
{
"key": "Accepted",
"doc_count": 8
},
{
"key": "Released",
"doc_count": 6
}
]
Now I'd like to add all of them up into a single field.
I tried using pipeline aggregations and even tried the following sum_bucket (which apparently only works on multi-bucket):
"total":{
"sum_bucket":{
"buckets_path": "slices"
}
}
Anyone able to help me out with this?
With sum_bucket and your already existent aggregation:
"aggs": {
"slices": {
"terms": {
"field": "status.raw",
"include": {
"pattern": "Accepted|Released|Closed"
}
}
},
"sum_total": {
"sum_bucket": {
"buckets_path": "slices._count"
}
}
}
What I would do is to use the filters aggregation instead and define all the buckets you need, like this:
{
"size": 0,
"query": {
"bool": {
"must": [
{
"query_string": {
"query": "*",
"analyze_wildcard": true
}
}
],
"must_not": []
}
},
"aggs": {
"slices": {
"filters": {
"filters": {
"accepted": {
"term": {
"status.raw": "Accepted"
}
},
"released": {
"term": {
"status.raw": "Released"
}
},
"closed": {
"term": {
"status.raw": "Closed"
}
},
"total": {
"terms": {
"status.raw": [
"Accepted",
"Released",
"Closed"
]
}
}
}
}
}
}
}
You could add count with value_count sub aggregation and then use sum_bucket pipeline aggregation
{
"aggs": {
"unique_status": {
"terms": {
"field": "status.raw",
"include": "Accepted|Released|Closed"
},
"aggs": {
"count": {
"value_count": {
"field": "status.raw"
}
}
}
},
"sum_status": {
"sum_bucket": {
"buckets_path": "unique_status>count"
}
}
},
"size": 0
}

Elasticsearch applying filters to aggregation

I'm trying to build a facets system using Elasticsearch to display the number of documents which match a query.
I'm currently doing this query on /_search?search_type=count:
{
"query": {
"query_string": {
"query": "status:(1|2) AND categories:A"
}
},
"aggs": {
"all_products": {
"global": {},
"aggs": {
"countries": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "country"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"categories": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "category"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"statuses": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "status"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
}
}
}
}
}
the documents have the following structure:
{
"id": 123,
"name": "Title",
"categories": ["A", "B", "C"],
"country": "United Kingdom",
"status": 1
}
so the output I'm looking for should be:
Country
UK: 123
USA: 1000
Category
Motors: 23
Fashion: 1100
Status
Active: 1120
Not Active: 3
I don't know how to filter properly the aggregations, because right now they are counting all the document in the specified field, without considering the query status:(1|2) AND categories:A.
The elastic version is 1.7.2.
You simply need to remove global aggregation since it is not influenced by the query, just move your countries, categories and statuses aggregations at the top level like this:
{
"query": {
"query_string": {
"query": "status:(1|2) AND categories:A"
}
},
"aggs": {
"countries": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "country"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"categories": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "category"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
},
"statuses": {
"aggs": {
"counter": {
"terms": ["min_doc_count": 0, "field": "status"],
"aggs": ["unique": ["cardinality": ["field": "id"]]]
}
}
}
}
}
Fabio. Ill see Your post on upwork, i have worked example for ES 2.4, may be it help You.
"index": "{{YOUR ELASTIC INDEX}}",
"type": "{{YOUR ELASTIC TYPE}}",
"body": {
"aggs": {
"trademarks": { // aggs NAME
"terms": {
"field": "id", // field name in ELASTIC base
"size": 100 // count of results YOU need
}
},
"materials": { //another aggs NAME
"terms": {
"field": "materials.name", // field name in ELASTIC base
"size": 100 / count of results YOU need
}
},
"certificate": {
"terms": {
"field": "certificate_type_id",
"size": 100
}
},
"country": {
"terms": {
"field": "country.id",
"size": 100
}
},
"price": {
"stats": {
"field": "price"
}
}
},
"from": 0, // start from
"size": 20, // results count
"query": {
"constant_score": {
"filter": { //apply filter
"bool": {
"should": [{ // all categories You need to show
"term": {
"categories": "10142"
}
}, {
"term": {
"categories": "10143"
}
}, {
"term": {
"categories": "10144"
}
}, {
"term": {
"categories": "10145"
}
}, {
"term": {
"categories": "12957"
}
}, {
"term": {
"categories": "13968"
}
}, {
"term": {
"categories": "14353"
}
}, {
"term": {
"categories": "16954"
}
}, {
"term": {
"categories": "18243"
}
}, {
"term": {
"categories": "10141"
}
}],
"must": [{ // if you want another filed to filter for example filter BY field trademark_id
"bool": {
"should": [{
"term": {
"trademark_id": "2872"
}
}, {
"term": {
"trademark_id": "2879"
}
}, {
"term": {
"trademark_id": "2914"
}
}]
}
}, {
"bool": { // filter by PRICE
"must": [{
"range": {
"price": {
"from": 5.97,
"to": 15752.69
}
}
}]
}
}]
}
}
}
},
"sort": { //here SORT BY desc or asc
"updated_at": "desc" //updated_at - field from ES base
}
}

Resources