---
"value rate":
  - do:
      bulk:
        index: test
        refresh: true
        body:
          - '{"index": {}}'
          - '{"timestamp": "2020-02-03T10:00:00Z", "val": 3}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-04T10:00:00Z", "val": 4}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-11T10:00:00Z", "val": 6}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-12T10:00:00Z", "val": 8}'
  - do:
      search:
        size: 0
        index: test
        body:
          aggs:
            by_date:
              date_histogram:
                field: timestamp
                calendar_interval: week
              aggs:
                rate:
                  rate:
                    field: val
                    unit: day

  - length: { aggregations.by_date.buckets: 2 }
  - match: { aggregations.by_date.buckets.0.rate.value: 1.0 }
  - match: { aggregations.by_date.buckets.1.rate.value: 2.0 }


---
"rate with doc_count":
  - requires:
      cluster_features: ["gte_v7.16.0"]
      reason: bug fixed in 7.16.0
  - do:
      bulk:
        index: test2
        refresh: true
        body:
          - '{"index": {}}'
          - '{"timestamp": "2021-09-14T22:33:37.477Z", "_doc_count": 10}'
          - '{"index": {}}'
          - '{"timestamp": "2021-09-14T22:35:37.477Z", "_doc_count": 5}'
          - '{"index": {}}'
          - '{"timestamp": "2021-09-14T22:35:38.477Z", "_doc_count": 1}'
          - '{"index": {}}'
          - '{"timestamp": "2021-09-14T22:36:08.477Z"}'
  - do:
      search:
        size: 0
        index: test2
        body:
          aggs:
            by_date:
              date_histogram:
                field: timestamp
                fixed_interval: 60s
              aggs:
                rate:
                  rate:
                    unit: minute

  - length: { aggregations.by_date.buckets: 4 }
  - match: { aggregations.by_date.buckets.0.rate.value: 10.0 }
  - match: { aggregations.by_date.buckets.1.rate.value: 0.0 }
  - match: { aggregations.by_date.buckets.2.rate.value: 6.0 }
  - match: { aggregations.by_date.buckets.3.rate.value: 1.0 }


---
"composite aggregation":
  - do:
      bulk:
        index: test3
        refresh: true
        body:
          - '{"index": {}}'
          - '{"timestamp": "2020-02-03T10:00:00Z", "dept": 1003, "val": 7}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-04T10:00:00Z", "dept": 1003, "val": 14}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-05T10:00:00Z", "dept": 1005, "val": 7}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-11T10:00:00Z", "dept": 1003, "val": 28}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-12T10:00:00Z", "dept": 1005, "val": 7}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-12T10:00:00Z", "dept": 1005, "val": 70}'
  - do:
      search:
        size: 0
        index: test3
        body:
          aggs:
            by_date:
              composite:
                sources:
                  - week:
                      date_histogram:
                        field: timestamp
                        calendar_interval: week
                  - department:
                      terms:
                        field: dept
              aggs:
                rate:
                  rate:
                    field: val
                    unit: day

  - length: { aggregations.by_date.buckets: 4 }
  - match: { aggregations.by_date.buckets.0.rate.value: 3.0 }
  - match: { aggregations.by_date.buckets.1.rate.value: 1.0 }
  - match: { aggregations.by_date.buckets.2.rate.value: 4.0 }
  - match: { aggregations.by_date.buckets.3.rate.value: 11.0 }


---
"value count mode":
  - do:
      bulk:
        index: test4
        refresh: true
        body:
          - '{"index": {}}'
          - '{"timestamp": "2020-02-01T10:00:00Z", "val": 1}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-01T11:00:00Z", "val": 20}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-01T12:00:00Z", "val": 300}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-02T10:00:00Z", "val": 4}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-02T11:00:00Z", "val": 50}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-04T10:00:00Z", "val": 6}'
  - do:
      search:
        size: 0
        index: test4
        body:
          aggs:
            by_date:
              date_histogram:
                field: timestamp
                calendar_interval: day
              aggs:
                rate:
                  rate:
                    field: val
                    unit: week
                    mode: value_count

  - length: { aggregations.by_date.buckets: 4 }
  - match: { aggregations.by_date.buckets.0.rate.value: 21.0 }
  - match: { aggregations.by_date.buckets.1.rate.value: 14.0 }
  - match: { aggregations.by_date.buckets.2.rate.value: 0.0 }
  - match: { aggregations.by_date.buckets.3.rate.value: 7.0 }


---
"runtime field with script":
  - do:
      bulk:
        index: test5
        refresh: true
        body:
          - '{"index": {}}'
          - '{"timestamp": "2020-02-03T10:00:00Z", "val": 1}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-04T10:00:00Z", "val": 2}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-11T10:00:00Z", "val": 4}'
          - '{"index": {}}'
          - '{"timestamp": "2020-02-12T10:00:00Z", "val": 5}'
  - do:
      search:
        size: 0
        index: test5
        body:
          runtime_mappings:
            val.adjusted:
              type: double
              script:
                source: "emit(doc['val'].value * params.adjustment)"
                params:
                  adjustment: 2.0
          aggs:
            by_date:
              date_histogram:
                field: timestamp
                calendar_interval: week
              aggs:
                rate:
                  rate:
                    field: val.adjusted

  - length: { aggregations.by_date.buckets: 2 }
  - match: { aggregations.by_date.buckets.0.rate.value: 6.0 }
  - match: { aggregations.by_date.buckets.1.rate.value: 18.0 }

---
"rate aggregation on counter field":
  - requires:
      cluster_features: ["gte_v8.7.0"]
      reason: "counter field support added in 8.7"
      test_runner_features: close_to

  - do:
      indices.create:
        index: test-rate
        body:
          settings:
            index:
              mode: time_series
              routing_path: [ host ]
              time_series:
                start_time: 2021-04-28T00:00:00Z
                end_time: 2021-04-29T00:00:00Z
          mappings:
            properties:
              "@timestamp":
                type: date
              host:
                type: keyword
                time_series_dimension: true
              bytes_gauge:
                type : long
                time_series_metric: gauge
              bytes_counter:
                type: long
                time_series_metric: counter
              byes:
                type: long

  - do:
      bulk:
        refresh: true
        index: test-rate
        body:
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:00.000Z", "host": "one", "bytes_counter": 1000, "bytes_gauge": 1000, "bytes": 1000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:01.000Z", "host": "one", "bytes_counter": 1100, "bytes_gauge": 100, "bytes": 100 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:02.000Z", "host": "one", "bytes_counter": 1200, "bytes_gauge": 100, "bytes": 100 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:03.000Z", "host": "one", "bytes_counter": 1250, "bytes_gauge": 50, "bytes": 50 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:04.000Z", "host": "one", "bytes_counter": 1310, "bytes_gauge": 60, "bytes": 60 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:05.000Z", "host": "one", "bytes_counter": 1350, "bytes_gauge": 40, "bytes": 40 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:06.000Z", "host": "one", "bytes_counter": 1420, "bytes_gauge": 70, "bytes": 70 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:07.000Z", "host": "one", "bytes_counter": 1500, "bytes_gauge": 80, "bytes": 80 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:08.000Z", "host": "one", "bytes_counter": 1520, "bytes_gauge": 20, "bytes": 20 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:50:09.000Z", "host": "one", "bytes_counter": 1550, "bytes_gauge": 30, "bytes": 30 }'

  - do:
      search:
        index: test-rate
        body:
          size: 0
          query:
            bool:
              filter:
                range:
                  "@timestamp":
                    gte: "2021-04-28T18:00:00.000Z"
                    lte: "2021-04-28T19:00:00.000Z"
          aggs:
            date_histogram:
              date_histogram:
                field: "@timestamp"
                fixed_interval: 1m
                time_zone: Europe/Ljubljana
                min_doc_count: 1
              aggs:
                8:
                  sum_bucket:
                    buckets_path: 8-bucket>8-metric
                9:
                  sum_bucket:
                    buckets_path: 9-bucket>9-metric
                10:
                  rate:
                    field: bytes_gauge
                    unit: second
                11:
                  rate:
                    field: bytes
                    unit: second
                8-bucket:
                  terms:
                    field: host
                    order:
                      _key: desc
                    size: 500
                  aggs:
                    8-metric:
                      rate:
                        field: bytes_gauge
                        unit: second
                9-bucket:
                  time_series: { }
                  aggs:
                    9-metric:
                      rate:
                        field: bytes_counter
                        unit: second

  - match: { hits.total.value: 10 }
  - length: { aggregations.date_histogram.buckets: 1 }
  - match: { aggregations.date_histogram.buckets.0.key_as_string: "2021-04-28T20:50:00.000+02:00" }
  - match: { aggregations.date_histogram.buckets.0.doc_count: 10 }
  - close_to: { aggregations.date_histogram.buckets.0.11.value: { value: 25.83, error: 0.01 } }
  - close_to: { aggregations.date_histogram.buckets.0.10.value: { value: 25.83, error: 0.01 } }
  - close_to: { aggregations.date_histogram.buckets.0.8.value: { value: 25.83, error: 0.01 } }
  # Rate aggregation on counters uses the actual bucket time interval instead of the parent date histogram calendar interval
  - close_to: { aggregations.date_histogram.buckets.0.9.value: { value: 61.11, error: 0.01 } }

---
"rate aggregation on counter field with unit":
  - requires:
      cluster_features: ["gte_v8.7.0"]
      reason: "counter field support added in 8.7"
      test_runner_features: close_to

  - do:
      indices.create:
        index: test-rate
        body:
          settings:
            number_of_shards: 3
            index:
              mode: time_series
              routing_path: [ host ]
              time_series:
                start_time: 2021-04-28T00:00:00Z
                end_time: 2021-04-29T00:00:00Z
          mappings:
            properties:
              "@timestamp":
                type: date
              host:
                type: keyword
                time_series_dimension: true
              counter:
                type : long
                time_series_metric: counter

  - do:
      bulk:
        refresh: true
        index: test-rate
        body:
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T12:00:00.000Z", "host": "one", "counter": 100000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T13:00:00.000Z", "host": "one", "counter": 210000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T14:00:00.000Z", "host": "one", "counter": 270000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T15:00:00.000Z", "host": "one", "counter": 395000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T16:00:00.000Z", "host": "one", "counter": 444000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T17:00:00.000Z", "host": "one", "counter": 499000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:00:00.000Z", "host": "one", "counter": 587000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T19:00:00.000Z", "host": "one", "counter": 712000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T20:00:00.000Z", "host": "one", "counter": 801000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T21:00:00.000Z", "host": "one", "counter": 888000 }'

  - do:
      search:
        index: test-rate
        body:
          size: 0
          aggs:
            ts:
              time_series:
                keyed: false
              aggs:
                rate-without-unit:
                  rate:
                    field: counter
                rate-second:
                  rate:
                    field: counter
                    unit: second
                rate-minute:
                  rate:
                    field: counter
                    unit: minute
                rate-hour:
                  rate:
                    field: counter
                    unit: hour
                rate-day:
                  rate:
                    field: counter
                    unit: day
                rate-week:
                  rate:
                    field: counter
                    unit: week
                rate-month:
                  rate:
                    field: counter
                    unit: month
                rate-quarter:
                  rate:
                    field: counter
                    unit: quarter
                rate-year:
                  rate:
                    field: counter
                    unit: year

  - match: { hits.total.value: 10 }
  - length: { aggregations.ts.buckets: 1 }
  - close_to: { aggregations.ts.buckets.0.rate-without-unit.value: { value: 24.32, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-second.value: { value: 24.32, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-minute.value: { value: 1459.25, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-hour.value: { value: 87555.55, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-day.value: { value: 2101333.33, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-week.value: { value: 14709333.33, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-month.value: { value: 63958020.00, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-quarter.value: { value: 191874060.00, error: 0.01 }}
  - close_to: { aggregations.ts.buckets.0.rate-year.value: { value: 767496240.00, error: 0.01 }}

---
"rate aggregation on counter field partial bucket":
  - requires:
      cluster_features: ["gte_v8.7.0"]
      reason: "counter field support added in 8.7"
      test_runner_features: close_to

  - do:
      indices.create:
        index: test-rate
        body:
          settings:
            index:
              mode: time_series
              routing_path: [ host ]
              time_series:
                start_time: 2021-04-28T00:00:00Z
                end_time: 2021-04-29T00:00:00Z
          mappings:
            properties:
              "@timestamp":
                type: date
              host:
                type: keyword
                time_series_dimension: true
              bytes_counter:
                type: long
                time_series_metric: counter

  - do:
      bulk:
        refresh: true
        index: test-rate
        body:
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:04.000Z", "host": "one", "bytes_counter": 1000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:14.000Z", "host": "one", "bytes_counter": 1100 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:24.000Z", "host": "one", "bytes_counter": 1200 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:34.000Z", "host": "one", "bytes_counter": 1250 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:44.000Z", "host": "one", "bytes_counter": 1310 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:54.000Z", "host": "one", "bytes_counter": 1350 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:01.000Z", "host": "two", "bytes_counter": 1000 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:11.000Z", "host": "two", "bytes_counter": 1100 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:21.000Z", "host": "two", "bytes_counter": 1200 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:31.000Z", "host": "two", "bytes_counter": 1250 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:41.000Z", "host": "two", "bytes_counter": 1310 }'
          - '{"index": {}}'
          - '{"@timestamp": "2021-04-28T18:01:51.000Z", "host": "two", "bytes_counter": 1350 }'

  - do:
      search:
        index: test-rate
        body:
          size: 0
          query:
            bool:
              filter:
                range:
                  "@timestamp":
                    gte: "2021-04-28T18:01:03.000Z"
                    lte: "2021-04-28T18:18:00.000Z"
          aggs:
            date_histogram:
              date_histogram:
                field: "@timestamp"
                calendar_interval: 1h
                time_zone: Europe/Ljubljana
                min_doc_count: 1
              aggs:
                counter_rate:
                  time_series:
                    keyed: false
                  aggs:
                    bytes_counter_rate:
                      rate:
                        field: bytes_counter
                        unit: second

  - match: { hits.total.value: 11 }
  - length: { aggregations.date_histogram.buckets: 1 }
  - match: { aggregations.date_histogram.buckets.0.key_as_string: "2021-04-28T20:00:00.000+02:00" }
  - match: { aggregations.date_histogram.buckets.0.doc_count: 11 }
  # NOTE: (1350 - 1000) / (54 - 4) = 350 / 50 = 7.0
  - close_to: { aggregations.date_histogram.buckets.0.counter_rate.buckets.0.bytes_counter_rate.value: { value: 7.00, error: 0.01 } }
  # NOTE: (1350 - 1100) / (51 - 11) = 250 / 40 = 6.25 (we filter out the first sample due to the bool range filter)
  - close_to: { aggregations.date_histogram.buckets.0.counter_rate.buckets.1.bytes_counter_rate.value: { value: 6.25, error: 0.01 } }
