我对Cassandra很在行,我不明白为什么我不能按日期过滤(希望在日期之间返回结果),例如:
CREATE TABLE test.service_bar(
service_bar_id UUID,
start_date_time timestamp,
end_date_time timestamp,
title varchar,
message text,
is_active boolean,
PRIMARY KEY((start_date_time, end_date_time))
);
然后这项工作:
SELECT start_date_time, end_date_time, is_active, message, service_bar_id, title
FROM test.service_bar
WHERE start_date_time = '2019-10-30 14:10:29' AND end_date_time = '2019-10-30 14:10:29'
LIMIT 500;
但是这个剂量
SELECT start_date_time, end_date_time, is_active, message, service_bar_id, title
FROM test.service_bar
WHERE start_date_time >= '2019-10-30 14:10:29' AND end_date_time <= '2019-10-30 14:10:29'
LIMIT 500;
我不能用 ALLOW FILTERING
我怎么能在Cassandra做这样的查询?
1条答案
按热度按时间vlf7wbxs1#
我不明白为什么我不能按日期过滤(想返回日期之间的结果)
你看到的行为是因为:
你已经定义了
start_date_time
以及end_date_time
作为复合分区密钥。由于cassandra使用分布式散列来确保正确的数据分布,所以分区不是按值的顺序存储的。它们由分区键的哈希令牌值存储。你可以通过使用token
分区键上的函数:这是行的默认顺序。这样做是因为每个节点负责特定的令牌范围,以确保数据在多节点集群中尽可能均匀地分布(这是通常的生产用例)。因此,cql对如何查询分区键有一些限制。这些限制可以避免编写错误的查询…例如不允许对分区键进行范围查询。
我怎么能在Cassandra做这样的查询?
这还应该告诉您,您应该构建表和查询,以确保它们可以通过对单个节点的请求来完成。有鉴于此,只有更改分区键,用例才会真正起作用。
开发团队实现像您这样的解决方案的一种方法是使用一种称为“时间bucketing”的建模技术,或者有时只是“bucketing”。在这种情况下,假设您每月编写的条目不会超过几千条。也许不是这样,但我会用它来做这个例子。然后我可以在月份分区,然后使用
_time
列作为群集键。这将按的值将所有行存储在一起
month_bucket
,在每个分区中,行将按start_date_time
以及end_date_time
按降序排列。现在它起作用了:但请注意,只能对单个集群键强制执行范围查询,如
start_date_time
上面。这不行:而且它不能工作,因为cassandra被设计成按顺序从磁盘读写数据。在一个查询中允许对多个列进行范围查询将需要cassandra进行随机读取,这是它所不擅长的。你可以用
ALLOW FILTERING
指令,但不建议这样做。虽然,使用ALLOW FILTERING
在小分区内可能会执行正常。