我有以下问题: 在我的Cassandra数据库中,我有几个用户发送了几条消息。 我的消息表具有以下结构:
CREATE TABLE messages (
recipient bigint,
sender bigint,
created_at text,
content text,
PRIMARY KEY((recipient, sender),created_at)
);
我需要计算用户在一天内发送的邮件数量。例如,在2017-01-01和2017-01-05之间
sender | created_at
1 2017-01-01
1 2017-01-01
2 2017-01-01
3 2017-01-02
3 2017-01-02
4 2017-01-03
4 2017-01-04
5 2017-01-04
我会得到结果
2017-01-01 = 2
2017-01-02 = 1
2017-01-03 = 1
2017-01-04 = 2
答案 0 :(得分:3)
从我所看到的情况来看,您无法对表结构执行此操作,因为您的分区键包含recipient
。要说,你根本不应该指望,因为counting keys in cassandra很难。
但是,如果你坚持计算这些键,我建议你采用两种方法:
CREATE TABLE counters_by_user (
sender bigint,
ts timestamp,
messages counter,
PRIMARY KEY (sender, ts)
)
此表允许您直接获取要查找的值。它允许您选择适当的"粒度"计数器,即如果您想要一个日常计数器,只需将时间戳存储在ts
字段的yyyy-mm-dd
字段中。如果您需要基于每小时的计数,请将其存储为yyyy-mm-dd HH:00
格式等...您只需要确切的sender
来获取结果,并且可以通过指定{{来查询范围1}}主键的组件。看看有关如何使用它们的Counters页面文档,并注意这种方法的主要缺点是Cassandra可以超过/不足,所以如果你需要在计数上迂腐,请注意你的步骤。 / p>
ts
每次在CREATE TABLE messages_by_sender (
sender bigint,
created_at timestamp,
PRIMARY KEY (sender, created_at)
);
表格中插入一行时,您都会在此处插入一行,当您需要计算发送的邮件时,只需运行messages
即可统计所有内容,或SELECT COUNT(*) FROM messages_by_sender WHERE sender=?
指定范围。如果每个SELECT COUNT(*) FROM messages_by_sender WHERE sender=? AND created_at > ? AND created_at < ?;
有大量消息,但这会导致效率低下,因为在Cassandra中计算密钥需要进行分区扫描。
答案 1 :(得分:1)
AFAIK,cassandra不允许进行类似SQL的聚合。你要么需要预先计算&amp;保留到另一个数据库中或在扫描/查询结果时进行计数。
将cassandra与hadoop&amp; amp;做一些map-reduce,但这似乎对你在这里尝试的东西有点过分。