自动间隔日期直方图聚合

编辑

自动间隔日期直方图聚合

编辑

一种类似于日期直方图的多桶聚合,区别在于它不是提供一个间隔来作为每个桶的宽度,而是提供一个目标桶数,表示需要的桶的数量,并且自动选择桶的间隔以最佳方式实现该目标。返回的桶的数量将始终小于或等于此目标数量。

buckets 字段是可选的,如果未指定,则默认为 10 个桶。

请求目标为 10 个桶。

resp = client.search(
    index="sales",
    size="0",
    aggs={
        "sales_over_time": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 10
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      sales_over_time: {
        auto_date_histogram: {
          field: 'date',
          buckets: 10
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  aggs: {
    sales_over_time: {
      auto_date_histogram: {
        field: "date",
        buckets: 10,
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "aggs": {
    "sales_over_time": {
      "auto_date_histogram": {
        "field": "date",
        "buckets": 10
      }
    }
  }
}

在内部,日期表示为一个 64 位数字,表示自纪元以来的毫秒时间戳。这些时间戳作为桶的 key 返回。key_as_string 是使用 format 参数指定的格式转换为格式化日期字符串的相同时间戳。

如果未指定 format,则它将使用字段映射中指定的第一个日期格式

resp = client.search(
    index="sales",
    size="0",
    aggs={
        "sales_over_time": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 5,
                "format": "yyyy-MM-dd"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      sales_over_time: {
        auto_date_histogram: {
          field: 'date',
          buckets: 5,
          format: 'yyyy-MM-dd'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  aggs: {
    sales_over_time: {
      auto_date_histogram: {
        field: "date",
        buckets: 5,
        format: "yyyy-MM-dd",
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "aggs": {
    "sales_over_time": {
      "auto_date_histogram": {
        "field": "date",
        "buckets": 5,
        "format": "yyyy-MM-dd" 
      }
    }
  }
}

支持表达日期格式模式

响应

{
  ...
  "aggregations": {
    "sales_over_time": {
      "buckets": [
        {
          "key_as_string": "2015-01-01",
          "key": 1420070400000,
          "doc_count": 3
        },
        {
          "key_as_string": "2015-02-01",
          "key": 1422748800000,
          "doc_count": 2
        },
        {
          "key_as_string": "2015-03-01",
          "key": 1425168000000,
          "doc_count": 2
        }
      ],
      "interval": "1M"
    }
  }
}

间隔

编辑

返回桶的间隔是基于聚合收集的数据选择的,因此返回的桶的数量小于或等于请求的数量。返回的可能间隔是

以 1、5、10 和 30 的倍数

分钟

以 1、5、10 和 30 的倍数

小时

以 1、3 和 12 的倍数

以 1 和 7 的倍数

以 1 和 3 的倍数

以 1、5、10、20、50 和 100 的倍数

在最坏的情况下,如果每日桶的数量对于请求的桶的数量来说太多,则返回的桶的数量将为请求的桶的数量的 1/7。

时区

编辑

日期时间在 Elasticsearch 中以 UTC 格式存储。默认情况下,所有的桶化和舍入操作也都在 UTC 中完成。time_zone 参数可用于指示桶化操作应使用不同的时区。

时区可以指定为 ISO 8601 UTC 偏移量(例如,+01:00-08:00),也可以指定为时区 ID,即 TZ 数据库中使用的标识符,如 America/Los_Angeles

考虑以下示例

resp = client.index(
    index="my-index-000001",
    id="1",
    refresh=True,
    document={
        "date": "2015-10-01T00:30:00Z"
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    id="2",
    refresh=True,
    document={
        "date": "2015-10-01T01:30:00Z"
    },
)
print(resp1)

resp2 = client.index(
    index="my-index-000001",
    id="3",
    refresh=True,
    document={
        "date": "2015-10-01T02:30:00Z"
    },
)
print(resp2)

resp3 = client.search(
    index="my-index-000001",
    size="0",
    aggs={
        "by_day": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 3
            }
        }
    },
)
print(resp3)
response = client.index(
  index: 'my-index-000001',
  id: 1,
  refresh: true,
  body: {
    date: '2015-10-01T00:30:00Z'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 2,
  refresh: true,
  body: {
    date: '2015-10-01T01:30:00Z'
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  id: 3,
  refresh: true,
  body: {
    date: '2015-10-01T02:30:00Z'
  }
)
puts response

response = client.search(
  index: 'my-index-000001',
  size: 0,
  body: {
    aggregations: {
      by_day: {
        auto_date_histogram: {
          field: 'date',
          buckets: 3
        }
      }
    }
  }
)
puts response
const response = await client.index({
  index: "my-index-000001",
  id: 1,
  refresh: "true",
  document: {
    date: "2015-10-01T00:30:00Z",
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  id: 2,
  refresh: "true",
  document: {
    date: "2015-10-01T01:30:00Z",
  },
});
console.log(response1);

const response2 = await client.index({
  index: "my-index-000001",
  id: 3,
  refresh: "true",
  document: {
    date: "2015-10-01T02:30:00Z",
  },
});
console.log(response2);

const response3 = await client.search({
  index: "my-index-000001",
  size: 0,
  aggs: {
    by_day: {
      auto_date_histogram: {
        field: "date",
        buckets: 3,
      },
    },
  },
});
console.log(response3);
PUT my-index-000001/_doc/1?refresh
{
  "date": "2015-10-01T00:30:00Z"
}

PUT my-index-000001/_doc/2?refresh
{
  "date": "2015-10-01T01:30:00Z"
}

PUT my-index-000001/_doc/3?refresh
{
  "date": "2015-10-01T02:30:00Z"
}

GET my-index-000001/_search?size=0
{
  "aggs": {
    "by_day": {
      "auto_date_histogram": {
        "field":     "date",
        "buckets" : 3
      }
    }
  }
}

如果未指定时区,则使用 UTC,返回从 2015 年 10 月 1 日午夜 UTC 开始的三个 1 小时桶

{
  ...
  "aggregations": {
    "by_day": {
      "buckets": [
        {
          "key_as_string": "2015-10-01T00:00:00.000Z",
          "key": 1443657600000,
          "doc_count": 1
        },
        {
          "key_as_string": "2015-10-01T01:00:00.000Z",
          "key": 1443661200000,
          "doc_count": 1
        },
        {
          "key_as_string": "2015-10-01T02:00:00.000Z",
          "key": 1443664800000,
          "doc_count": 1
        }
      ],
      "interval": "1h"
    }
  }
}

如果指定了 -01:00time_zone,则午夜从 UTC 午夜前一小时开始

resp = client.search(
    index="my-index-000001",
    size="0",
    aggs={
        "by_day": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 3,
                "time_zone": "-01:00"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  size: 0,
  body: {
    aggregations: {
      by_day: {
        auto_date_histogram: {
          field: 'date',
          buckets: 3,
          time_zone: '-01:00'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  size: 0,
  aggs: {
    by_day: {
      auto_date_histogram: {
        field: "date",
        buckets: 3,
        time_zone: "-01:00",
      },
    },
  },
});
console.log(response);
GET my-index-000001/_search?size=0
{
  "aggs": {
    "by_day": {
      "auto_date_histogram": {
        "field":     "date",
        "buckets" : 3,
        "time_zone": "-01:00"
      }
    }
  }
}

现在仍然返回三个 1 小时桶,但第一个桶从 2015 年 9 月 30 日晚上 11:00 开始,因为这是指定时区中该桶的本地时间。

{
  ...
  "aggregations": {
    "by_day": {
      "buckets": [
        {
          "key_as_string": "2015-09-30T23:00:00.000-01:00", 
          "key": 1443657600000,
          "doc_count": 1
        },
        {
          "key_as_string": "2015-10-01T00:00:00.000-01:00",
          "key": 1443661200000,
          "doc_count": 1
        },
        {
          "key_as_string": "2015-10-01T01:00:00.000-01:00",
          "key": 1443664800000,
          "doc_count": 1
        }
      ],
      "interval": "1h"
    }
  }
}

key_as_string 值表示指定时区中每天的午夜。

当使用遵循 DST(夏令时)更改的时区时,接近这些更改发生时刻的桶的大小可能与相邻的桶略有不同。例如,考虑 CET 时区中的 DST 开始:2016 年 3 月 27 日凌晨 2 点,时钟向前拨快 1 小时至当地时间凌晨 3 点。如果聚合的结果是每日桶,则覆盖该日期的桶将仅保存 23 小时的数据,而不是其他桶通常的 24 小时。对于较短的间隔(例如 12 小时)也是如此。在这里,当 DST 转换发生时,我们将在 3 月 27 日上午只有一个 11 小时的桶。

最小间隔参数

编辑

minimum_interval 允许调用者指定应使用的最小舍入间隔。这可以使收集过程更有效率,因为聚合不会尝试以低于 minimum_interval 的任何间隔进行舍入。

minimum_interval 可接受的单位是

  • 小时
  • 分钟
resp = client.search(
    index="sales",
    size="0",
    aggs={
        "sale_date": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 10,
                "minimum_interval": "minute"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      sale_date: {
        auto_date_histogram: {
          field: 'date',
          buckets: 10,
          minimum_interval: 'minute'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  aggs: {
    sale_date: {
      auto_date_histogram: {
        field: "date",
        buckets: 10,
        minimum_interval: "minute",
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "aggs": {
    "sale_date": {
      "auto_date_histogram": {
        "field": "date",
        "buckets": 10,
        "minimum_interval": "minute"
      }
    }
  }
}

缺失值

编辑

missing 参数定义了应如何处理缺少值的文档。默认情况下,它们将被忽略,但也可以将它们视为具有值。

resp = client.search(
    index="sales",
    size="0",
    aggs={
        "sale_date": {
            "auto_date_histogram": {
                "field": "date",
                "buckets": 10,
                "missing": "2000/01/01"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'sales',
  size: 0,
  body: {
    aggregations: {
      sale_date: {
        auto_date_histogram: {
          field: 'date',
          buckets: 10,
          missing: '2000/01/01'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "sales",
  size: 0,
  aggs: {
    sale_date: {
      auto_date_histogram: {
        field: "date",
        buckets: 10,
        missing: "2000/01/01",
      },
    },
  },
});
console.log(response);
POST /sales/_search?size=0
{
  "aggs": {
    "sale_date": {
      "auto_date_histogram": {
        "field": "date",
        "buckets": 10,
        "missing": "2000/01/01" 
      }
    }
  }
}

publish_date 字段中没有值的文档将与具有值 2000-01-01 的文档落在同一个桶中。