cassandra 1.x中按日期范围查询的最简单示例

时间:2011-12-26 19:43:12

标签: nosql cassandra

我想存储一个ID和一个日期,我想从dateA到dateB检索所有条目,我需要具备哪些才能执行select from my_column_family where date >= dateA and date < dateB;

2 个答案:

答案 0 :(得分:1)

#cassandra(IRC)的那些人帮助我找到了一条路,有很多微妙的细节,所以我想在这里记录一下。

首先你需要声明一个类似于此的列族(来自cassandra-cli的例子):

create column family users with comparator=UTF8Type and key_validation_class=UTF8Type and column_metadata=[
    {column_name: id, validation_class: LongType}
    {column_name: name, validation_class: UTF8Type, index_type: KEYS}
    {column_name: age, validation_class: LongType}
];
关于此声明的一些重要事项:

  • 比较器和key_validation_class可以使用字符串作为键名
  • 第一个声明的列是特殊的,它是用于寻址每一行的“行键”,因此不能包含重复值(INSERT实际上是一个UPSERT,因此当重复时,新值会覆盖旧值)
  • 第二列声明其值的“二级索引”(更多内容见下文)
  • 日期存储为Long数据类型,解释权归客户端

现在让我们添加一些值:

set users[1][name] = john;
set users[1][age]  = 19;
set users[2][name] = jane;
set users[2][age]  = 21;
set users[3][name] = john;
set users[3][age]  = 32;

根据这个:http://pkghosh.wordpress.com/2011/03/02/cassandra-secondary-index-patterns/ Cassandra不支持<运算符,它的作用是手动排除不匹配的行,但它会在结果集之后执行,它也会拒绝除非进行实际过滤,否则这样做。

这意味着像get users where age > 20;这样的查询会返回null,但如果我们添加一个包含=的谓词,它就会神奇地起作用。

这里的二级索引很重要,没有它你就不能使用=所以在这个例子中我可以get users where name = jane;但我不能要求get users where age = 21;

有趣的是,在使用=之后<工作,因此有了二级索引,您可以要求get users where name = john and age > 20;并且它会正确过滤。

答案 1 :(得分:1)

有几种方法可以解决这个问题。最简单的可能是您自己的答案中提到的具有相等限制的二级索引解决方案。我使用了这种方法,添加了一个名为“valid”的附加列,将值设置为1.然后查询可以变为,其中valid = 1,日期&gt; nnnn

其他解决方案需要额外的列族和其他查询。

加载数据时,创建并添加到包含时间戳作为键的列族,每个条目将列出所有用户ID作为列名。

如果订购了分区策略,则单个 RangeSliceQuery 可以将日期范围指定为键范围,并获取每个键的所有列。然后使用每个用户ID的列值迭代结果键,如果需要,查询原始列族以获取与每个id关联的数据。 Cassandra始终存储已排序的列名称,并且在阅读时可以反转。

但是,作为documented,有序分区器并不理想,导致热点和节点负载均衡困难。

如果没有有序的分区程序,仍然保留timestamp列族,则必须在加载数据时创建另一个列族,您可以将所有时间戳存储为一个或多个已知键下的列(例如“created”或“updated” “)。对于已知密钥,第一个查询是 SliceQuery ,然后列名称(作为时间戳)将为 MultigetSliceQuery提供密钥 到timestamp列系列。

我已经使用了这方面的变体,通常添加复合键或列以获得额外的灵活性。