说我已经定义了下表和二级索引:
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是否总是返回按分区键排序的行?
我发现这个有趣的原因是我的应用程序中的其他自然查询包括:
让我感到惊讶的是,在ItemUpdates上的select语句中添加一个子句ORDER BY time DESC
会产生错误消息&#34;不支持带有第二个索引的ORDER BY。&#34;
(2)(如何)在通过选择索引列来缩小查询范围时,是否可以对分区键执行范围查询?
答案 0 :(得分:2)
你应该在cassandra上获得的唯一自然“自动”排序是针对宽行的列。使用murmur3时的分区不会被“排序”,因为这会破坏随机分布(afaik)。索引作为宽行存储在“隐藏”表中的每个节点上。当对索引进行过滤时,它会在节点上点击“分区”,而值是该分区中的行(对应于该节点上的匹配行)。使用不同的数据集和不同的列尝试查询。也许您拥有的数据会导致结果排序。
(2)就目前而言,您只能对群集密钥进行范围查询,而不能对分区密钥进行范围查询。通常,为了进行有效的查询,您应该尝试命中一个(或几个)分区,并对群集密钥上的群集密钥/范围查询上的索引/过滤器进行过滤。如果您尝试不命中分区,它将成为一个群集范围的操作,这通常不是很好。如果您希望进行集群范围分析(ala map reduce style),请查看Apache Spark。 Spark cassandra集成非常好并且正在变得更好。