我的架构非常类似于: -
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的新手,即使它要求我们进行架构更改,也欢迎任何建议。 :)
答案 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。