【问题标题】:Cassandra: cannot restrict 2 columns using clustering key(version 2.1.9)Cassandra:不能使用集群键限制 2 列(版本 2.1.9)
【发布时间】:2017-09-10 12:56:37
【问题描述】:

我有一个与此非常相似的架构:-

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 的新手,欢迎任何和所有建议,即使它需要我们进行架构更改。 :)

【问题讨论】:

    标签: cassandra nosql


    【解决方案1】:

    你没有说你运行的是哪个版本的 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 的结束日期,因为它们在 compound range 的范围内。要摆脱这样的行,您可能需要在客户端进行一些过滤。

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

    【讨论】:

    • 非常感谢您的建议,所以这里我们基本上是在start_date的基础上进行过滤,在这种情况下不考虑end_date。我可以用 start_date> 'date' 和 start_date
    • 您可以这样做,然后在客户端过滤结束日期。它的工作原理几乎相同,但是您可能会在需要在客户端丢弃的范围的开头和结尾处获得更多行。要了解发生了什么,您必须考虑在分区内排序的行。当您选择该分区的一部分时,您指定了分区内的起点和终点,然后获取介于两者之间的所有内容。
    • 可能是我能找到的最接近的解决方案,谢谢 :)
    猜你喜欢
    • 2015-04-18
    • 2015-11-30
    • 2017-02-10
    • 1970-01-01
    • 2021-08-15
    • 2013-08-16
    • 1970-01-01
    • 2013-09-09
    • 2015-08-09
    相关资源
    最近更新 更多