Kalmar
Kalmar

Reputation: 65

Filtering range aggregation buckets

I am trying to filter results of aggregation based on range aggregation

Right now i have something like this

  "aggregations": {
        "count_by_field": {
            "terms": {
                "field": "fieldXXX",
                "size": 10,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                    {
                        "_count": "desc"
                    },
                    {
                        "_key": "asc"
                    }
                ]
            },
            "aggregations": {
                "range": {
                    "date_range": {
                        "field": "@timestamp",
                        "format": "d-MM-yyyy HH-mm",
                        "ranges": [
                            {
                                "key": "last1h",
                                "from": "now-1H",
                                "to": "now"
                            },
                            {
                                "key": "last24h",
                                "from": "now-24H",
                                "to": "now"
                            }
                        ],
                        "keyed": true
                    }
                }
            }
        }
    }

which provides me with response like this

{
  "_shards": {
    "total": 15,
    "failed": 0,
    "successful": 15,
    "skipped": 0
  },
  "hits": {
    "hits": [],
    "total": 3128,
    "max_score": 0
  },
  "took": 15,
  "timed_out": false,
  "aggregations": {
    "count_by_field": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "doc_count": 1740,
          "range": {
            "buckets": {
              "last24h": {
                "from_as_string": "10-01-2021 13-40",
                "doc_count": 1740,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610286031263,
                "to": 1610372431263
              },
              "last1h": {
                "from_as_string": "11-01-2021 12-40",
                "doc_count": 16,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610368831263,
                "to": 1610372431263
              }
            }
          },
          "key": "field_value1"
        },
        {
          "doc_count": 1318,
          "range": {
            "buckets": {
              "last24h": {
                "from_as_string": "10-01-2021 13-40",
                "doc_count": 1318,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610286031263,
                "to": 1610372431263
              },
              "last1h": {
                "from_as_string": "11-01-2021 12-40",
                "doc_count": 49,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610368831263,
                "to": 1610372431263
              }
            }
          },
          "key": "field_value2"
        },
        {
          "doc_count": 36,
          "range": {
            "buckets": {
              "last24h": {
                "from_as_string": "10-01-2021 13-40",
                "doc_count": 36,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610286031263,
                "to": 1610372431263
              },
              "last1h": {
                "from_as_string": "11-01-2021 12-40",
                "doc_count": 0,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610368831263,
                "to": 1610372431263
              }
            }
          },
          "key": "field_value3"
        },
        {
          "doc_count": 34,
          "range": {
            "buckets": {
              "last24h": {
                "from_as_string": "10-01-2021 13-40",
                "doc_count": 34,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610286031263,
                "to": 1610372431263
              },
              "last1h": {
                "from_as_string": "11-01-2021 12-40",
                "doc_count": 0,
                "to_as_string": "11-01-2021 13-40",
                "from": 1610368831263,
                "to": 1610372431263
              }
            }
          },
          "key": "field_value4"
        }
      ]
    }
  }
}

and now i would like to filter only buckets from count_by_field

that it range buckets results fulfill this condition

last1h count > last24h count / 24

i have tried bucket_scripts and bucket_selectors but with no success:(

Maybe someone sees an option to filter it:)

Upvotes: 0

Views: 138

Answers (1)

Joe - Check out my books
Joe - Check out my books

Reputation: 16925

What you're after is a bucket_selector because that's the agg what can skip children of a multi-bucket aggregation.

I don't know if you can access the members of a ranges aggregation in a bucket script but you can arrive at the solution with a little bit of refactoring into two separate range-restricted filter aggs:

{
  "size": 0,
  "aggregations": {
    "count_by_field": {
      "terms": {
        "field": "fieldXXX",
        "size": 10,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "last1h": {
          "filter": {
            "range": {
              "@timestamp": {
                "gte": "now-1H"
              }
            }
          },
          "aggs": {
            "range": {
              "date_range": {
                "field": "@timestamp",
                "format": "d-MM-yyyy HH-mm",
                "ranges": [
                  {
                    "key": "last1h",
                    "from": "now-1H",
                    "to": "now"
                  }
                ],
                "keyed": true
              }
            }
          }
        },
        "last24h": {
          "filter": {
            "range": {
              "@timestamp": {
                "gte": "now-24H"
              }
            }
          },
          "aggs": {
            "range": {
              "date_range": {
                "field": "@timestamp",
                "format": "d-MM-yyyy HH-mm",
                "ranges": [
                  {
                    "key": "last24h",
                    "from": "now-24H",
                    "to": "now"
                  }
                ],
                "keyed": true
              }
            }
          }
        },
        "bucket_selector_agg": {
          "bucket_selector": {
            "buckets_path": {
              "last1h": "last1h._count",
              "last24h": "last24h._count"
            },
            "script": "params.last1h > (params.last24h / 24)"
          }
        }
      }
    }
  }
}

Upvotes: 2

Related Questions