我可以在 Cassandra 2.1 中对集合进行多重查询吗?

Can I do a multi query on collections in Cassandra 2.1?

在 Cassandra 2.1 中,我们可以通过在列上创建二级索引来查询集合。

cqlsh:play> select * from songs where tags contains 't1';

 id                                   | tags         | title

--------------------------------------+--------------+-------

 e99f8f30-d212-11e4-bc9e-5d1b1922b94d | {'t1', 't2'} | Song1

但我想查询多个值 - 像这样:

select * from songs where tags contains 't1|t2';

这可能吗?

你不能:Cassandra 不支持 OR 运算符。

干杯, 卡罗

Is this possible?

有点,是的。你应该这样做吗?不,不是真的。让我解释一下...

虽然 Carlo 的 CQL 不支持 OR 是正确的,但它可以与 AND 一起使用。也就是说,你想查询两个标签的存在,你可以这样做:

aploetz@cqlsh:Whosebug> SELECT * FROM songs
  WHERE tags CONTAINS 't2' AND tags CONTAINS 't1' ALLOW FILTERING;

 id                                   | tags         | title
--------------------------------------+--------------+-------
 75e46eb2-292a-42d0-8330-510fb35c635b | {'t1', 't2'} | Song1

(1 rows)

虽然这个技术上可行,但它是一个糟糕的想法

  • Multi-key 查询已被识别为 anti-pattern。使用同时的异步查询通常比使用 INCONTAINS 为多个键返回行更快。 DataStax 在 SELECT 文档中有一个标题为 When Not To Use In 的部分,您应该仔细阅读。
  • 二级索引表现不佳,collection 上的二级索引比 single-valued 对应的二级索引表现更差是合乎逻辑的。事实上,该文档有一整节内容是关于 When Not To Use An Index 的,您在使用它们之前应该仔细阅读。
  • 要使 AND 运算符在 collection 上工作两次,需要 ALLOW FILTERINGALLOW FILTERING 基本上带回您拥有的每一行(来自每个节点),然后 然后 过滤结果。如果您有一个大型数据集 and/or 个节点,您应该 永远不要 使用需要 ALLOW FILTERING 才能完成的查询。

正确的方法是构建一个额外的查询table,使用tag作为分区键(和id作为唯一性的聚类键)。

CREATE TABLE songsByTag (
  tag text,
  title text,
  id uuid,
  PRIMARY KEY ((tag),id));

这将允许您通过特定标签查询歌曲,而不需要二级索引。虽然这将允许您随后使用 IN(本质上是 OR),但对每个键(标签)的多个异步查询仍然会更快。