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

时间:2015-03-26 11:18:59

标签: cassandra cql

在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';

这可能吗?

2 个答案:

答案 0 :(得分:3)

  

这可能吗?

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

虽然Carlo的正确性是CQL不支持OR,但可以使用AND。也就是说,您想要查询两个标记的存在,您可以这样做:

aploetz@cqlsh:stackoverflow> 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)

虽然技术上有效,但它是可怕的IDEA

  • 多键查询已被确定为反模式。使用同步异步查询通常比使用INCONTAINS为多个键恢复行更快。 DataStax有一段标题为When Not To Use InSELECT文档,您应该阅读。
  • 二级索引的表现不佳,而且集合上的二级索引的性能甚至比它们的单值索引更差。实际上,文档在When Not To Use An Index上有一个完整的部分,在使用之前你应该真正阅读。
  • 要使AND运算符在集合上工作两次,需要ALLOW FILTERINGALLOW FILTERING基本上会返回您拥有的每一行(来自每个节点),然后会过滤结果。如果您有大型数据集和/或多个节点,则从不使用需要ALLOW FILTERING完成的查询。

正确的方法是构建一个额外的查询表,其中tag作为分区键(并id作为唯一性的聚类键)。< / p>

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

这将允许您通过特定标签查询歌曲,而无需二级索引。虽然这样你就可以使用IN(基本上是OR),但每个密钥(标记)的多个异步查询仍然会更快。

答案 1 :(得分:0)

您无法在Cassandra中支持OR运营商。

干杯, 卡罗