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

Nosql cassandra 1.x中按日期范围查询的最简单示例,nosql,cassandra,Nosql,Cassandra,我想存储一个ID和一个日期,我想检索dateA到dateB的所有条目,我需要做什么才能从我的列族中执行选择,其中date>=dateA和datennnn 其他解决方案需要额外的列族和额外的查询 在加载数据时,创建并添加到一个列族中,该列族包含作为键的时间戳,并且每个条目将列出所有作为列名的用户ID 如果分区策略是有序的,那么单个RangeSicleQuery可以将日期范围指定为键范围,并获取每个键的所有列。然后使用每个用户id的列值遍历结果键,如果需要,查询原始列族中与每个id关联的数据。Cas

我想存储一个ID和一个日期,我想检索dateA到dateB的所有条目,我需要做什么才能从我的列族中执行选择,其中date>=dateA和date 卡桑德拉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}
];
关于这一宣言,有几点很重要:

comparator和key_validation_类能够使用字符串作为键名 第一个声明的列是特殊的,它是用于寻址每一行的行键,因此不能包含重复的值INSERT实际上是一个UPSERT,因此当存在重复项时,新值将覆盖旧值 第二列对其值声明了一个二级索引,下面将详细介绍 日期存储为长数据类型,解释由客户机决定 现在让我们添加一些值:

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;
据此:卡桑德拉不支持20人;将返回null,但如果我们添加一个包含=的谓词,它将神奇地工作

这里是次要索引很重要的地方,没有它,你就不能使用=所以在这个例子中,我可以得到name=jane的用户;但我不能要求get用户年龄=21岁


有趣的是,使用后=20;它会正确过滤。

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

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

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

如果分区策略是有序的,那么单个RangeSicleQuery可以将日期范围指定为键范围,并获取每个键的所有列。然后使用每个用户id的列值遍历结果键,如果需要,查询原始列族中与每个id关联的数据。Cassandra始终存储已排序的列名,并且在读取时可以反转

但是,正如所述,有序分区器并不理想,导致热点和节点负载平衡困难

如果没有有序分区器,仍然保留时间戳列族,则在加载数据时必须创建另一个列族,以便将所有时间戳作为列存储在一个或多个已知键下,例如“创建”或“更新”。第一个查询是已知键的SliceQuery,然后作为时间戳的列名将为MultigetSliceQuery向timestamp列族提供键


我在这方面使用了一些变体,通常添加复合键或列以增加灵活性。

顺便说一句,这没有答案:而且对于旧版本来说,这是一种解决问题的方法,但是它依赖于二级索引列上的重复值,这可能不是最好的主意;我很想听听其他选择,并讨论每种选择的利弊。有人告诉我,这也可以用TimeUUID来完成,并从有序分区器中获取_切片,但我不知道如何做到这一点,而且我还读到有序分区器在平衡方面很差。此外,这对超级列也不起作用,因为它们不支持二级索引。实际上,事实上,only=works在二级索引上并不神奇,这是因为索引的性质不是btree。我真的需要添加一个伪列,并在每个插入中将其设置为1,以便能够按范围过滤完全不相关的其他列吗?这些工具对我不利…我相信是的,只有一个二级索引。。但是看看一个完全不相关的问题,了解CQL3如何利用复合材料来解决您的问题。有关更多详细信息,请参阅。我了解到,如果我们将列用作复合主键的一部分,则可以高效执行范围查询,但这仅适用于建议禁用的有序分区器,因为它会扰乱分片策略。。。使用虚拟列并不是更好。它需要全表扫描,因此在大型数据集上速度非常慢。对于Cassandra中的大型分布式数据集,是否还有其他范围过滤解决方案?列总是按顺序存储的,因此如果列名是复合的,则可以通过ColumnSiceIterator等获得有效的查询。如果行键是复合的,则分区器将指示是。在CQL示例中,请注意主键与行键不同。