【发布时间】:2021-09-12 01:00:38
【问题描述】:
我需要为 cassndra 做这个查询:
select * from classes where students = null allow filtering;
学生是一个集合
但看起来 set 不允许 = 运算符。
【问题讨论】:
我需要为 cassndra 做这个查询:
select * from classes where students = null allow filtering;
学生是一个集合
但看起来 set 不允许 = 运算符。
【问题讨论】:
为了测试这一点,我关注了Indexing a Collection 上的 DataStax 文档。
> CREATE TABLE cyclist_career_teams ( id UUID PRIMARY KEY, lastname text, teams set<text> );
> CREATE INDEX team_idx ON cyclist_career_teams ( teams );
创建表并在teams 集上设置二级索引,然后我插入了一些测试数据:
> SELECT lastname,teams FROM cyclist_career_teams ;
lastname | teams
-----------------+---------------------------------------------------------------------------------------------------------
Vos | {'Neiderland bloeit', 'Rabobank Womens Team', 'Rabobonk-Liv Giant', 'Rabobonk-Liv Womens Cycling Team'}
Van Der Breggen | {'Rabobonk-Liv Womens Cycling Team', 'Sengers Ladies Cycling Team', 'Team Flexpoint'}
Brand | {'AA Drink - Leontien.nl', 'Rabobonk-Liv Giant', 'Rabobonk-Liv Womens Cycling Team'}
Armistead | null
请注意,对于 Lizzie Armistead,我故意省略了 teams 列的值。虽然 CQL 不允许集合类型上的等于“=”关系,但它确实允许 CONTAINS。但是,尝试将其与 null 一起使用会产生不同的错误:
> SELECT lastname,teams FROM cyclist_career_teams WHERE teams CONTAINS null;
[Invalid query] message="Unsupported null value for column teams"
这种行为的原因,与 Cassandra 如何对 null 值和“null”关键字进行一些特殊处理有关。本质上,写入 null 会创建一个墓碑,这是 Cassandra 的结构,表示删除。
即使 Cassandra 对 null 的处理不是一个因素,您仍然会面临“null”值不是唯一的问题,并且您的查询必须轮询集群中的每个节点强>。这样的用例是众所周知的反模式。不幸的是,Cassandra 不擅长查询不存在的数据(或过滤键值)。
您可以尝试的一件事是使用字符串文字来指示空值,如下所示:
> INSERT INTO cyclist_career_teams (id,lastname) VALUES (uuid(),'Armistead',{'empty'});
> SELECT lastname,teams FROM cyclist_career_teams WHERE teams CONTAINS 'empty';
lastname | teams
-----------+-----------
Armistead | {'empty'}
(1 rows)
但老实说,由于上述反模式,我不能真诚地推荐这种方法。但是在创建时添加了一些应用程序逻辑,“空”字符串文字可能适合您。
【讨论】: