postgresql 查询等效于弹性搜索中具有扩展边界的日期直方图
postgresql query equivalent of date histogram with extended bounds in elastic search
我有一个 table 包含以下列:
column1
column2
timestamp
event_id
c1v1
c2v1
2021-03-11 00:00:00
1
c1v2
c2v2
2021-03-11 01:03:00
1
c1v3
c2v3
2021-03-12 10:00:00
2
c1v4
c2v4
2021-03-13 20:00:00
1
c1v5
c2v5
2021-03-13 11:00:00
2
c1v6
c2v6
2021-03-13 00:00:00
3
c1v7
c2v7
2021-03-14 00:00:00
2
我有 start_time = 2021-03-10 05:14:00
和 end_time = 2021-03-15 15:12:19
我正在对此数据进行弹性搜索查询
- 从 start_time 到 end_time
1 天的分区
- 计算每个分区中的文档数量(具有 0 个文档的分区也是因为扩展边界)
- 对于每个分区,在 event_id
列中查找唯一值的数量
{
"query": {
"bool": {
"filter":
[
{
"term": {"column1": "some_value"}
},
{
"term": {"column2": "some_value"}
},
{
"range": {
"timestamp": {
"gte": "<start_time>",
"lt": "<end_time>"
}
}
}
]
}
},
"aggs": {
"timestamp": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1d",
"extended_bounds": {
"min": "<start_time>",
"max": "<end_time>"
}
},
"aggs": {
"unique_values": {
"cardinality": {
"field": "event_id"
}
}
}
}
}
}
我需要帮助来创建一个具有相同功能的 sql 查询。
输出:
timestamp
doc_count
unique_values
2021-03-10
0
0
2021-03-11
2
1
2021-03-12
1
1
2021-03-13
3
3
2021-03-14
1
1
2021-03-15
0
0
更新:我提出了这个查询,但我得到的值接近 es 中的值,但不准确。这也不会 return 有 0 个文档的日期。
SELECT
date_floor,
count(date_floor) AS cnt_date_floor,
count(DISTINCT(event_id)) AS cnt_dst_event_id
FROM (
SELECT
event_id,
DATE(timestamp) AS date_floor
FROM
<table_name>
WHERE
date BETWEEN date'<start_date>' AND date'<end_date>' AND
timestamp >= timestamp'<start_time>' AND
timestamp < timestamp'<end_time>' AND
column1 IN ('some val') AND
column2 = some_val)
GROUP BY date_floor
其中 start_date 和 end_date 是 start_time 和 end_time
的 floor_dates
您可以使用 generate_series 来生成您需要的天数。离开加入这个系列并按天分组。
SELECT day,
count(event_id) as doc_count,
count(distinct event_id) as unique_values
FROM generate_series('2021-03-10T00:00:00', '2021-03-15T00:00:00', interval '1 day') as g(day)
LEFT JOIN test ON date_trunc('day', tstamp) = day
GROUP BY day
ORDER BY day;
您的查询对 column1 和 column2 进行了一些额外的过滤,这不是问题的一部分,但将它们重新添加进去应该很简单。
如果您不能在查询之外将开始时间设置为一天的开始,只需添加 date_trunc('day', )而不是开始时间。
这是一个fiddle。
我有一个 table 包含以下列:
column1 | column2 | timestamp | event_id |
---|---|---|---|
c1v1 | c2v1 | 2021-03-11 00:00:00 | 1 |
c1v2 | c2v2 | 2021-03-11 01:03:00 | 1 |
c1v3 | c2v3 | 2021-03-12 10:00:00 | 2 |
c1v4 | c2v4 | 2021-03-13 20:00:00 | 1 |
c1v5 | c2v5 | 2021-03-13 11:00:00 | 2 |
c1v6 | c2v6 | 2021-03-13 00:00:00 | 3 |
c1v7 | c2v7 | 2021-03-14 00:00:00 | 2 |
我有 start_time = 2021-03-10 05:14:00
和 end_time = 2021-03-15 15:12:19
我正在对此数据进行弹性搜索查询
- 从 start_time 到 end_time 1 天的分区
- 计算每个分区中的文档数量(具有 0 个文档的分区也是因为扩展边界)
- 对于每个分区,在 event_id 列中查找唯一值的数量
{
"query": {
"bool": {
"filter":
[
{
"term": {"column1": "some_value"}
},
{
"term": {"column2": "some_value"}
},
{
"range": {
"timestamp": {
"gte": "<start_time>",
"lt": "<end_time>"
}
}
}
]
}
},
"aggs": {
"timestamp": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1d",
"extended_bounds": {
"min": "<start_time>",
"max": "<end_time>"
}
},
"aggs": {
"unique_values": {
"cardinality": {
"field": "event_id"
}
}
}
}
}
}
我需要帮助来创建一个具有相同功能的 sql 查询。
输出:
timestamp | doc_count | unique_values |
---|---|---|
2021-03-10 | 0 | 0 |
2021-03-11 | 2 | 1 |
2021-03-12 | 1 | 1 |
2021-03-13 | 3 | 3 |
2021-03-14 | 1 | 1 |
2021-03-15 | 0 | 0 |
更新:我提出了这个查询,但我得到的值接近 es 中的值,但不准确。这也不会 return 有 0 个文档的日期。
SELECT
date_floor,
count(date_floor) AS cnt_date_floor,
count(DISTINCT(event_id)) AS cnt_dst_event_id
FROM (
SELECT
event_id,
DATE(timestamp) AS date_floor
FROM
<table_name>
WHERE
date BETWEEN date'<start_date>' AND date'<end_date>' AND
timestamp >= timestamp'<start_time>' AND
timestamp < timestamp'<end_time>' AND
column1 IN ('some val') AND
column2 = some_val)
GROUP BY date_floor
其中 start_date 和 end_date 是 start_time 和 end_time
的 floor_dates您可以使用 generate_series 来生成您需要的天数。离开加入这个系列并按天分组。
SELECT day,
count(event_id) as doc_count,
count(distinct event_id) as unique_values
FROM generate_series('2021-03-10T00:00:00', '2021-03-15T00:00:00', interval '1 day') as g(day)
LEFT JOIN test ON date_trunc('day', tstamp) = day
GROUP BY day
ORDER BY day;
您的查询对 column1 和 column2 进行了一些额外的过滤,这不是问题的一部分,但将它们重新添加进去应该很简单。
如果您不能在查询之外将开始时间设置为一天的开始,只需添加 date_trunc('day',
这是一个fiddle。