Cassandra CLUSTERING ORDER BY无效并显示正确的结果

时间:2017-04-08 16:54:54

标签: cassandra cql cassandra-3.0

您好我已经创建了一个用于存储此类数据的表

CREATE TABLE keyspace.test (
name text,
date text,
time double,
entry text,
details text,
PRIMARY KEY ((name, date), time)
) WITH CLUSTERING ORDER BY (time DESC);

并将数据插入到表中。但是这样的查询会产生无序结果。

SELECT * FROM keyspace.test where device_id   name ='anand' and date in ('2017-04-01','2017-04-02','2017-04-03','2017-04-05') ;

我的桌面设计有问题吗。

2 个答案:

答案 0 :(得分:2)

我认为你误解了cassandra聚类键顺序。 Cassandra在单个分区中使用群集键对数据进行排序。

这适用于您的情况cassandra在一个名称和日期内将聚类关键时间排序数据。

示例:让我们插入一些数据

INSERT INTO test (name , date , time , entry ) VALUES ('anand', '2017-04-01', 1, 'a');
INSERT INTO test (name , date , time , entry ) VALUES ('anand', '2017-04-01', 2, 'b');
INSERT INTO test (name , date , time , entry ) VALUES ('anand', '2017-04-01', 3, 'c');
INSERT INTO test (name , date , time , entry ) VALUES ('anand', '2017-04-02', 0, 'nil');
INSERT INTO test (name , date , time , entry ) VALUES ('anand', '2017-04-02', 4, 'd');

如果我们使用您的查询选择数据:

SELECT * FROM test where name ='anand' and date in ('2017-04-01','2017-04-02','2017-04-03','2017-04-05') ;

输出:

 name  | date       | time | details | entry
-------+------------+------+---------+-------
 anand | 2017-04-01 |    3 |    null |     c
 anand | 2017-04-01 |    2 |    null |     b
 anand | 2017-04-01 |    1 |    null |     a
 anand | 2017-04-02 |    4 |    null |     d
 anand | 2017-04-02 |    0 |    null |   nil

您可以看到时间3,2,1位于单个分区中anand:2017-04-01按desc排序,时间4,0位于单个分区anand:2017-04-02内,以desc排序。 Cassandra不会在不同的分区之间进行排序。

这是doc:

  

在表定义中,聚类列是复合主键定义的一部分,而不是第一列,即为分区键保留的位置。列在单个分区中聚集在多个行中。聚类顺序由复合主键定义中列的位置确定。

来源:http://docs.datastax.com/en/cql/3.1/cql/ddl/ddl_compound_keys_c.html

顺便说一下,为什么您的数据字段为text类型且time字段为double类型?
您可以将date字段用作date类型,将time用作timestamp类型。

答案 1 :(得分:2)

您正在使用的查询是o.k.但它可能不会像你期望的那样表现,因为协调员不会根据分区对结果进行排序。我也偶尔碰到这个问题。

它的解决方案非常简单,基本上在客户端执行您需要的4个单独查询然后在那里合并结果会好得多。简而言之,IN运算符给集群中的协调节点带来了很大的压力,对这个主题有一个很好的解读:

https://lostechies.com/ryansvihla/2014/09/22/cassandra-query-patterns-not-using-the-in-query-for-multiple-partitions/