不支持具有二元索引的ORDER BY



我使用的是带有最新CQL的cassandra 2.1。

这是我的桌子;索引:

CREATE TABLE mydata.chats_new (
    id bigint,
    adid bigint,
    fromdemail text,
    fromemail text,
    fromjid text,
    messagebody text,
    messagedatetime text,
    messageid text,
    messagetype text,
    todemail text,
    toemail text,
    tojid text,
    PRIMARY KEY(messageid,messagedatetime)
);

CREATE INDEX user_fromJid ON mydata.chats_new (fromjid);
CREATE INDEX user_toJid ON mydata.chats_new (tojid);
CREATE INDEX user_adid ON mydata.chats_new (adid);

当我执行这个查询时:

select * from chats_new WHERE fromjid='test' AND toJid='test1' ORDER BY messagedatetime DESC;

我得到了这个错误:

code=2200 [Invalid query] message="ORDER BY with 2ndary indexes is not supported."

那么应该如何获取这些数据呢?

select * from chats_new 
WHERE fromjid='test' AND toJid='test1' 
ORDER BY messagedatetime DESC;

code=2200[无效查询]message="不支持具有二元索引的ORDER BY。"

为了让这个查询的WHERE子句起作用,我将构建一个特定的查询表,如下所示:

CREATE TABLE mydata.chats_new_by_fromjid_and_tojid (
    id bigint,
    adid bigint,
    fromdemail text,
    fromemail text,
    fromjid text,
    messagebody text,
    messagedatetime text,
    messageid text,
    messagetype text,
    todemail text,
    toemail text,
    tojid text,
    PRIMARY KEY((fromjid, tojid), messagedatetime, messageid)
);

请注意主键的定义。这将从fromjidtojid中创建一个分区密钥。虽然这将允许您在两个字段上进行查询,但还要求在该表的所有查询中指定这两个字段。但这就是为什么他们称之为"查询表",因为它通常是为一个特定的查询而设计的。

至于主键中的其余字段,我保留messagedatetime作为第一个集群列,以确保磁盘上的排序顺序。Cassandra中的默认排序是升序,所以如果您想在查询时更改它,那么ORDER BY messagedatetime DESC就会发挥作用。最后,我确保messageid是第二个集群列,以帮助确保主键的唯一性(假设messageid是唯一的)。

现在,这个查询将起作用:

select * from chats_new_by_fromjid_and_tojid 
WHERE fromjid='test' AND toJid='test1'
ORDER BY messagedatetime DESC;

如果您需要根据其他条件查询此数据,我强烈建议您创建其他查询表。请记住,Cassandra最适合使用专门为其服务的每个查询设计的表。复制几次数据是可以的,因为磁盘空间很便宜。。。操作时间不是。

此外,DataStax有一篇关于何时不使用辅助索引的好文章。它绝对值得一读。

最新更新