第二个索引上的Cassandra SELECT总是按分区键排序?

时间:2014-11-04 08:52:43

标签: indexing cassandra cql3 range-query

说我已经定义了下表和二级索引:

CREATE TABLE ItemUpdates (
    time         timestamp,
    item_name    text,
    item_context text,
    item_descr   text,
    tags         map<text, int>,
    PRIMARY KEY ((time, item_name, item_context))
);

CREATE INDEX ItemUpdateByName
    ON ItemUpdates(item_name);

CREATE INDEX ItemUpdateByContext
    ON ItemUpdates(item_context);

CREATE INDEX ItemUpdateByTag
    ON ItemUpdates(KEYS(tags));

有关数据模型的一般背景信息:项目在上下文中具有唯一名称,因此(item_name,item_context)是项目的自然键。标签有一些与之相关的价值。

我的应用程序中的自然查询是&#34;显示项目X上带有特定标记的所有更新&#34;。这转化为:

SELECT * FROM ItemUpdates
    WHERE item_name='x'
        AND item_context='a'
        AND tags CONTAINS KEY 't';

当我尝试一些查询时,我注意到虽然群集使用了Murmur3Partitioner,但结果是按时间排序的。当您考虑Cassandra将二级索引存储为宽行时,这是有道理的,并且列的名称按其名称排序。

(1)在(n)(一组)索引列上选择时,Cassandra是否总是返回按分区键排序的行?

我发现这个有趣的原因是我的应用程序中的其他自然查询包括:

  • 从日期D
  • 获取项目X上的所有更新
  • 获取第X项的最近300次更新

让我感到惊讶的是,在ItemUpdates上的select语句中添加一个子句ORDER BY time DESC会产生错误消息&#34;不支持带有第二个索引的ORDER BY。&#34;

(2)(如何)在通过选择索引列来缩小查询范围时,是否可以对分区键执行范围查询?

1 个答案:

答案 0 :(得分:2)

你应该在cassandra上获得的唯一自然“自动”排序是针对宽行的列。使用murmur3时的分区不会被“排序”,因为这会破坏随机分布(afaik)。索引作为宽行存储在“隐藏”表中的每个节点上。当对索引进行过滤时,它会在节点上点击“分区”,而值是该分区中的行(对应于该节点上的匹配行)。使用不同的数据集和不同的列尝试查询。也许您拥有的数据会导致结果排序。

(2)就目前而言,您只能对群集密钥进行范围查询,而不能对分区密钥进行范围查询。通常,为了进行有效的查询,您应该尝试命中一个(或几个)分区,并对群集密钥上的群集密钥/范围查询上的索引/过滤器进行过滤。如果您尝试不命中分区,它将成为一个群集范围的操作,这通常不是很好。如果您希望进行集群范围分析(ala map reduce style),请查看Apache Spark。 Spark cassandra集成非常好并且正在变得更好。