Cassandra:无法使用群集密钥限制2列(版本2.1.9)

时间:2015-09-18 07:57:09

标签: cassandra nosql

我的架构非常类似于: -

create table x(id int, start_date timestamp, end_date timestamp, 
primary key((id), start_date, end_date)) 
with clustering order by (start_date desc, end_date desc);

现在我遇到了一个问题,我必须在开始日期和结束日期之间进行查询。这样的事情: -

select count(*) from x where id=2 and start_date > 'date' and end_date < 'date' ;

但它给出了类似于以下内容的错误: -

InvalidRequest: code=2200 [Invalid query] message="PRIMARY KEY column "end_date" 
cannot be restricted (preceding column "start_date" is restricted 
by a non-EQ relation)"

我是cassandra的新手,即使它要求我们进行架构更改,也欢迎任何建议。 :)

1 个答案:

答案 0 :(得分:2)

您没有说您正在运行哪个版本的Cassandra,但在2.2及更高版本中,您可以对群集列执行多列切片限制。这可以接近你想要的。 CQL中的语法有点难看,但基本上你必须指定所有指定的聚类列的起始范围,比如复合键。重要的是要考虑首先按第一列排序的行,然后在第二列排序的行中。

假设我们有这些数据:

SELECT * from x;

 id | start_date               | end_date
----+--------------------------+--------------------------
  2 | 2015-09-01 09:16:47+0000 | 2015-11-01 09:16:47+0000
  2 | 2015-08-01 09:16:47+0000 | 2015-10-01 09:16:47+0000
  2 | 2015-07-01 09:16:47+0000 | 2015-09-01 09:16:47+0000
  2 | 2015-06-01 09:16:47+0000 | 2015-10-01 09:16:47+0000

现在让我们根据两个日期进行选择:

SELECT * from x where id=2 
    and (start_date,end_date) >= ('2015-07-01 09:16:47+0000','2015-07-01 09:16:47+0000') 
    and (start_date,end_date) <= ('2015-09-01 09:16:47+0000','2015-09-01 09:16:47+0000');

 id | start_date               | end_date
----+--------------------------+--------------------------
  2 | 2015-08-01 09:16:47+0000 | 2015-10-01 09:16:47+0000
  2 | 2015-07-01 09:16:47+0000 | 2015-09-01 09:16:47+0000

现在您会注意到其中一个结束日期似乎晚于我们的限制,但事实并非如此。由于事物首先按start_date排序,因此您将获得匹配的start_date的所有结束日期,因为它们位于复合范围的范围内。为了摆脱这样的行,你可能需要在客户端进行一些过滤。

在“多列切片限制”下查看更多信息here