我尝试选择在索引列中包含至少一行具有特定值的分区键。
使用当前解决方案可以满足所有其他要求:
最后,我需要能够选择某个用户创建报告的所有办公室。根据cassadra文档,我在用户列上添加了索引。
该表定义为:
create table report(
office uuid,
type text,
insert_date timestamp,
...
created_by uuid,
...
primary key(office, type, insert_date));
create index created_by_idx on report (created_by);
如果我没记错的话,使用该索引就像有一个辅助表,描述如下:
create table report2(
created_by uuid,
office uuid,
type text,
insert_date timestamp,
...
primary key(created_by ,office, type, insert_date));
我可以成功运行如下查询:
select office from report where created_by = ?
但这会导致使用相同的办公室密钥的多行是正确的:每个用户可以在每个办公室中创建多个报告。
现在,我在软件级别过滤重复的办公室,但是我问自己,是否有可能在提取期间直接过滤该数据。
我尝试过:
select distinct office from report where created_by = ?
导致
SELECT DISTINCT with WHERE clause only supports restriction by partition key and/or static columns.
然后我尝试了:
select office from report where created_by = ? group by office
会给我正确的结果,但会发出警告:
Aggregation query used without partition key
这可能是一个问题吗?如何处理cassandra这样的查询,在这种情况下可以忽略此警告?最后,使用这样的查询对
select * ...
的where子句相同吗?
答案 0 :(得分:1)
Cassandra不支持您描述的功能是有原因的-这是因为它效率低下:
首先,如您所述,二级索引必须确实列出所有匹配的行键,而不仅仅是不同的匹配分区键。这是因为您可能会要求所有行,而不仅仅是唯一的分区键,因此数据必须存在。之所以必须将这些数据保留在索引中,另一个原因是每一行都可以单独删除(或过期),因此Cassandra需要跟踪所有这些行,以确定整个分区是否仍然存在,或者不再存在。 / p>
现在,由于我们已经在搜索结果列表中列出了所有行的键,因此仅输出“不同的”分区键是一种低效的操作...如果您在一个分区中有一百万个匹配的行,那么Cassandra将需要在仅输出一个结果之前扫描所有它们。 Cassandra通常不会让用户用低效的操作射击自己的脚(例如,查看如何需要“允许过滤”才能在SELECT查询中明确允许低效的过滤。)
话虽这么说,将来的Cassandra版本应该允许您请求的“ SELECT DISTINCT”请求是合理的,也许要求用户说“ ALLOW FILTERING”以承认它可能很慢。另外,另一种实现可能涉及较慢的更新(每个行更新将检查分区的活动性),但随后需要快速读取。 Scylla考虑了这样的实现,但也没有实现(请参见https://github.com/scylladb/scylla/issues/3435)。