我有桌子-
CREATE TABLE IF NOT EXISTS Chat(
id UUID,
time timestamp,
idSender UUID,
message varchar,
PRIMARY KEY ((id),time))
WITH CLUSTERING ORDER BY(time DESC);
我想按时间对邮件进行排序。但是当我运行时,Cassandra不会对我的表进行排序:
select * from chat order by time
它显示消息
Error from server: code=2200 [Invalid query]
message="ORDER BY is only supported when the
partition key is restricted by an EQ or an IN.
如何按时间对表格进行排序?
答案 0 :(得分:4)
要清楚,Cassandra使用集群键(在您的情况下为time
)来强制执行磁盘上的排序顺序。但是它只能在分区键内强制执行该命令。
所以这应该起作用:
SELECT * FROM chat WHERE id = db14789e-ede0-4852-a397-d0ccc7d8349e;
请注意,您不必指定ORDER BY
,因为您已经在表定义中完成了此操作。除非您当然要翻转排序方向(升序与降序)。
如果这没有帮助,那么您将需要使用不同的分区键重建表,这样做是合理的。然后按该分区键进行的查询将返回按time
排序的查询。但是在Cassandra中,您不能简单地选择表中的所有行,并期望它主要由分区键的哈希标记值以外的任何其他东西排序。
我不使用它,因为id是唯一的
提示:如果您不打算通过它查询,那么将它用作分区键就没有意义了。
需要获取最近100条消息
因此,可能最好的方法是使用一种称为“存储桶”的分区技术。在这种情况下,我们可以(例如)每天创建一个存储桶,该存储桶看起来像这样:
CREATE TABLE IF NOT EXISTS chat_by_day(
day TEXT,
id UUID,
time timestamp,
idSender UUID,
message TEXT,
PRIMARY KEY ((day),time,id))
WITH CLUSTERING ORDER BY(time DESC,id ASC);
插入一些数据后,我可以按天查询,并查看按时间排序的结果:
cassdba@cqlsh:stackoverflow> SELECT time,message FROM chat_by_day
WHERE day='20180621' LIMIT 100;
time | message
---------------------------------+--------------------------------------------------------
2018-06-21 14:51:14.863000+0000 | No...I am your father.
2018-06-21 14:51:14.858000+0000 | If only you could see what I have seen with your eyes.
2018-06-21 14:51:14.854000+0000 | Game over man!
2018-06-21 14:50:13.369000+0000 | There can be only one.
(4 rows)
现在,这只是一个例子,但希望它可以为您指明正确的方向。
奇怪的是无法按时间排序
好吧,这是设计要追溯到Cassandra的建造方式。分布式数据库可能仍然在一个节点上具有所有副本(例如Neo4j),但是 sharded 数据库(根据定义)却没有。在大型系统中,您绝对不希望有“热”节点(一个节点的数据比另一个节点多),因此,以便于分布的方式对其进行重新排序就更有意义。考虑到这一点,您将更容易理解为什么快速整体数据排序/排序成为次要考虑因素。