How to Filter Aggregated Results in Elasticsearch for List Type Field Used in Field Aggregation?

26 Views Asked by At

I want to do aggregation on the list field in elasticsearch. But while doing same, as this is list field if there is other value along with searched value inside the list then aggregation will also give those in the result. Is there any way to filter this aggregation results to get only matching records. Also want this to work with pagination as well.

Example:

Doc:

{
id: 1,
field: [foo, bar, foobar]
},
{
id: 2,
field: [foo]
},
{
id: 3,
field: [foo, foobar]
}

ES query:

{
  "aggFilter": {
    "filter": {
      "terms": {
        "field": [
          "foo"
        ],
        "boost": 1
      }
    },
    "aggregations": {
      "fieldAggregation0": {
        "terms": {
          "field": "field",
          "size": 1000,
          "min_doc_count": 1,
          "shard_min_doc_count": 0,
          "show_term_doc_count_error": false,
          "order": [
            {
              "_count": "desc"
            },
            {
              "_key": "asc"
            }
          ]
        }
      }
    }
  }
}

Output:

{
    "_key" : "foo",
    "doc_count" : 3
},
{
    "_key" : "foobar",
    "doc_count" : 2,
},
{
    "_key" : "bar",
    "doc_count" : 1
}

Expecting:

{
    "_key" : "foo",
    "doc_count" : 3
}

Tried with bucket_selector but it gives error that value to be filtered(value at bucket_path) should be numeric and in my case I want to filter _key which is string.

1

There are 1 best solutions below

0
G0l0s On

The terms aggregation has the include parameter to filter terms (exclude as well)

Documents

POST /filter_array_items/_bulk
{"create":{"_id":1}}
{"id":"1","field":["foo","bar","foobar"]}
{"create":{"_id":2}}
{"id":"2","field":["foo"]}
{"create":{"_id":3}}
{"id":"3","field":["foo","foobar"]}

Modified query

GET /filter_array_items/_search?filter_path=aggregations
{
    "query": {
        "terms": {
            "field": [
                "foo"
            ]
        }
    },
    "aggs": {
        "fieldAggregation0": {
            "terms": {
                "field": "field.keyword",
                "size": 1000,
                "include": "foo",
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                    {
                        "_count": "desc"
                    },
                    {
                        "_key": "asc"
                    }
                ]
            }
        }
    }
}

Response

{
    "aggregations" : {
        "fieldAggregation0" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
                {
                    "key" : "foo",
                    "doc_count" : 3
                }
            ]
        }
    }
}

I use the terms query to filter documents for aggregation

Use the bucket_sort aggregation to paginate results