# Advanced filtering for aggregations

**URL:** <https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320>\
**Category:** Kibana\
**Created:** [December 30, 2019, 8:13am UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320 "2019-12-30T08:13:43Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Allard\_Poldermans](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/allard_poldermans/32/55354_2.png) [@Allard\_Poldermans](https://discuss.elastic.co/u/Allard_Poldermans)\
**Post date:** [December 30, 2019, 8:13am UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320/1 "2019-12-30T08:13:43Z")

</div>

I have an index containing OrderLines in Elastic Search which contains customer name, product name, price.

My objective is to create a visualization (datalist) and aggregate by Customer Name, and find the totals for all customers that have bought product X, but have **not** bought product Y.

The final display should be something like :

# Customer Name Total Value Product A value

Cust1 1000 (all bought products) 100 (only product X)  
.....

Is this possible to do in Kibana ?

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [December 30, 2019, 10:19am UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320/2 "2019-12-30T10:19:50Z")

</div>

Hi, I don't think this will be possible with regular visualizations as you need features that aren't available via the UI (e.g. the bucket selector aggregation). Your best bet would be a raw elasticsearch queries, but there is currently no way to visualize the results of those as a table without writing a custom visualization plugin.

If you are also fine with a horizontal bar visualization, you can look into [vega](https://www.elastic.co/guide/en/kibana/current/vega-graph.html) as it allows you to specify your custom query. In your case you can use a query similar to this one:

```auto
GET /your_index/_search
{
  "size": 0,
  "aggs": {
    "customers": {
      // aggregate by customer field
      "terms": {
        "field": "customer",
        "size": 10
      },
      "aggs": {
      // sum up all totals  
        "all_total": {
          "sum": {
            "field": "total"
          }
        },
      // sum up just the totals of product x (by doing a filter aggregation first)
        "x_total": {
          "filter": {
            "term": {
              "product": "X"
            }
          },
          "aggs": {
            "sum": {
              "sum": {
                "field": "total"
              }
            }
          }
        },
       // get count of Y product purchases for the current customer (to filter the bucket later)
        "hasY": {
          "filter": {
            "term": {
              "product": "Y"
            }
          },
          "aggs": {
            "count": {
              "value_count": {
                "field": "product"
              }
            }
          }
        },
       // get count of X product purchases for the current customer (to filter the bucket later)
        "hasX": {
          "filter": {
            "term": {
              "product": "X"
            }
          },
          "aggs": {
            "count": {
              "value_count": {
                "field": "product"
              }
            }
          }
        },
       // actually filter down the bucket by the script containing the condition
        "bucket_filter": {
          "bucket_selector": {
            "buckets_path": {
              "xCount": "hasX.count",
              "yCount": "hasY.count"
            },
            "script": "params.xCount > 0 && params.yCount == 0"
          }
        }
      }
    }
  }
}

```

It makes sense to first build the query in the dev tools and when it produces the right results you can plug it into a vega spec. Feel free to ask questions if you get stuck on this route.

---

<div class="post-metadata">

**Author:** ![Allard\_Poldermans](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/allard_poldermans/32/55354_2.png) [@Allard\_Poldermans](https://discuss.elastic.co/u/Allard_Poldermans)\
**Post date:** [December 30, 2019, 3:44pm UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320/3 "2019-12-30T15:44:57Z")

</div>

Thank you very much for your reply and effort.

In the meantime I found another way to get a bit closer :

In Kibana you can create a datatable and aggregate by CustomerName, and then create multiple metrics. For each metric (of type SUM) you can specify in the advanced settings a filter, similar to :

```
{ "script" : "if (doc['Product.Name.keyword'].value =='Product X' ) { return _value; } return 0" }

```

I also do the same for Product Y.

This will give me the dataset with a column for the total sale, the sale for Product X and the sale for Product Y (which sometimes is 0).

I can then export the results to Excel and filter out the rows where the sale for Product Y is 0.

I still wonder if there is a way to hide a row completely when there is no sale for Product Y.

---

<div class="post-metadata">

**Author:** ![flash1293](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/flash1293/32/41227_2.png) [@flash1293](https://discuss.elastic.co/u/flash1293)\
**Post date:** [December 30, 2019, 4:11pm UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320/4 "2019-12-30T16:11:22Z")

</div>

It's great you found a way that works for your use case - I actually typed out this solution half-way and then deleted it because I missed the part with filtering out the rows that don't have Product Y. Instead of advanced JSON input you could also use [scripted fields](https://www.elastic.co/guide/en/kibana/current/scripted-fields.html) which are defined on an index pattern level.

> I still wonder if there is a way to hide a row completely when there is no sale for Product Y.

This is what the `bucket_selector` is doing on Elasticsearch side - unfortunately there is currently no way I know of to do it on the Kibana side that's supported by the standard table visualization.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [January 27, 2020, 4:11pm UTC](https://discuss.elastic.co/t/advanced-filtering-for-aggregations/213320/5 "2020-01-27T16:11:25Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
