1

假设我定义了下表和二级索引:

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) 是项目的自然键。标签有一些与之相关的价值。

我的应用程序中的一个自然查询是“向我显示带有特定标签的项目 X 的​​所有更新”。这转化为:

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

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

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

我觉得这很有趣的原因是我的应用程序中的其他自然查询包括:

  • 从日期 D 获取项目 X 的​​所有更新
  • 获取项目 X 的​​ 300 条最新更新

令我惊讶的是,ORDER BY time DESC在 ItemUpdates 上的 select 语句中添加子句会导致错误消息“不支持带有 2ndary 索引的 ORDER BY”。

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

4

1 回答 1

2

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

(2) 就目前而言,您只能对集群键进行范围查询,而不能对分区键进行范围查询。一般来说,为了高效查询,您应该尝试点击一个(或几个)分区,并在索引上过滤/在集群键上过滤/在集群键上进行范围查询。如果你试图不命中一个分区,它就会变成一个集群范围的操作,这通常不是很好。如果您正在寻找进行集群范围的分析(ala map reduce 风格),请查看 Apache Spark。Spark cassandra 集成非常好,并且越来越好。

于 2014-11-04T10:25:22.357 回答