我正在使用cassandra 2.1和最新的CQL。
这是我的桌子&索引:
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."
那么应该如何获取这些数据?
答案 0 :(得分:6)
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)
);
请注意主键定义。这会在fromjid
和tojid
之外创建分区键。虽然这将允许您在两个字段上进行查询,但它也要求在此表的所有查询中指定两个字段。但这就是为什么他们称之为"查询表",因为它通常用于提供一个特定查询。
对于主键中的其余字段,我将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在when not to use a secondary index上有一篇很棒的文章。它绝对值得一读。