gpt4 book ai didi

node.js - 无法使用 timeuuid 作为主键执行时间序列查询

转载 作者:太空宇宙 更新时间:2023-11-03 23:13:52 25 4
gpt4 key购买 nike

我的目标是对给定时间范围(fromDate < stats_date_id < toDate)内每个不同的provider_id值的messages_sent和emails_sent进行求和,但不指定provider_id。换句话说,我需要了解指定时间范围内的所有提供商,并对它们的 messages_sent 和 emails_sent 进行求和。

我有一个使用 Express-cassandra 架构(在 Node.js 中)的 Cassandra 表,如下所示:

module.exports = {
fields: {
stats_provider_id: {
type: 'uuid',
default: {
'$db_function': 'uuid()'
}
},
stats_date_id: {
type: 'timeuuid',
default: {
'$db_function': 'now()'
}
},
provider_id: 'uuid',
provider_name: 'text',
messages_sent: 'int',
emails_sent: 'int'
},
key: [
[
'stats_date_id'
],
'created_at'
],
table_name: 'stats_provider',
options: {
timestamps: {
createdAt: 'created_at', // defaults to createdAt
updatedAt: 'updated_at' // defaults to updatedAt
}
}
}

为了让它工作,我希望它像执行以下操作一样简单:

let query = {
stats_date_id: {
'$gt': db.models.minTimeuuid(fromDate),
'$lt': db.models.maxTimeuuid(toDate)
}
};
let selectQueries = [
'provider_name',
'provider_id',
'count(direct_sent) as direct_sent',
'count(messages_sent) as messages_sent',
'count(emails_sent) as emails_sent',
];
// Query stats_provider table
let providerData = await db.models.instance.StatsProvider.findAsync(query, {select: selectQueries});

然而,这提示需要过滤结果:在数据库上查找查询时出错 -> ResponseError: 无法执行此查询,因为它可能涉及数据过滤,因此可能具有不可预测的性能

我猜您不能拥有主键并对其进行日期范围搜索?如果是这样,这种查询的正确方法是什么?

最佳答案

因此,虽然没有使用过 Express-Cassandra,但我可以告诉您,在分区键上运行范围查询是一个硬性的“不”。原因是 Cassandra 无法确定该查询的单个 Node ,因此它必须轮询每个 Node 。由于这本质上是跨多个 Node 对表进行完整扫描,因此它会抛出该错误以防止您运行错误的查询。

但是,您可以对集群键运行范围查询,前提是您要过滤该键之前的所有键。就您而言,如果我没读错,您的主键如下所示:

主键(stats_date_id、created_at)

主键定义会出现问题,原因有两个:

  1. stats_date_id 是一个 TimeUUID。这对于数据分发来说非常。但这对于查询灵 active 来说很糟糕。事实上,您需要提供准确的 TimeUUID 值才能返回特定分区的数据。由于 TimeUUID 具有毫秒精度,因此您需要知道查询的精确时间精确到毫秒。也许您有能力做到这一点,但通常这并不能成为一个好的分区键。

  2. 该分区 (created_at) 下的任何行都必须共享该确切时间,这通常会导致分区:集群键出现大量 1:1 基数比。

我对解决此问题的建议是在基数级别稍低的日期列上进行分区。考虑一下在特定时间范围内通常会保存多少条提供商消息。还要选择不会存储太多提供程序消息的内容,因为您不希望未绑定(bind)的分区增长(Cassandra 有每个分区 20 亿个单元的硬限制)。

也许类似:PRIMARY KEY (week,created_at)

那么您的 CQL 查询可能类似于:

SELECT * FROM stats_provider
WHERE week='201909w1'
AND created_at > '20190901'
AND created_at < '20190905';

TL;DR;

  1. 对时间段进行分区的精度不如精确到毫秒,但足够大以满足您通常的查询。
  2. 对分区内的第一个聚类键应用范围过滤器。

关于node.js - 无法使用 timeuuid 作为主键执行时间序列查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58004388/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com