日期:2014-05-16 浏览次数:20490 次
最近在使用Cassandra,版本为1.1.1, CQL版本为3.0.0。遇到如下问题。
目标:利用复合主键进行查询和排序,并想利用二级索引进行多条件查询。
首先CQL建表,用到复合主键(instigator, startedAt):
?
CREATE TABLE altercations ( instigator text, startedAt text, shipsDestroyed text, energyUsed text,allianceInvolvement text, PRIMARY KEY (instigator, startedAt) );
然后建立二级索引:
CREATE INDEX ON altercations (shipsDestroyed);
执行CREATE INDEX 操作后,Cassandra报错:
java.lang.IllegalArgumentException at java.nio.Buffer.limit(Buffer.java:249) at org.apache.cassandra.db.marshal.AbstractCompositeType.getBytes(AbstractCompositeType.java:51) at org.apache.cassandra.db.marshal.AbstractCompositeType.getWithShortLength(AbstractCompositeType.java:60) at org.apache.cassandra.db.marshal.AbstractCompositeType.getString(AbstractCompositeType.java:140) at org.apache.cassandra.config.CFMetaData.getDefaultIndexName(CFMetaData.java:875) at org.apache.cassandra.config.CFMetaData.addDefaultIndexNames(CFMetaData.java:863) at org.apache.cassandra.cql3.statements.CreateIndexStatement.announceMigration(CreateIndexStatement.java:90) at org.apache.cassandra.cql3.statements.SchemaAlteringStatement.execute(SchemaAlteringStatement.java:99) at org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:108) at org.apache.cassandra.cql3.QueryProcessor.process(QueryProcessor.java:121) at org.apache.cassandra.thrift.CassandraServer.execute_cql_query(CassandraServer.java:1237) at org.apache.cassandra.thrift.Cassandra$Processor$execute_cql_query.getResult(Cassandra.java:3542) at org.apache.cassandra.thrift.Cassandra$Processor$execute_cql_query.getResult(Cassandra.java:3530) at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:32) at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:34) at org.apache.cassandra.thrift.CustomTThreadPoolServer$WorkerProcess.run(CustomTThreadPoolServer.java:186) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)
?但是,把复合主键改为单一主键的话,这个错误是没有的。
?
?
经过一天的思考,发现确实不能建立二级索引了。
本人对二级索引建立的内部原理不是很清楚,但参考Apache Cassandra 1.1 Documentation,发现确实只能用主键查询(就是多建几个主键),而且多条件查询时(除最后一个外)必须用“=”表达式。
比如像这样:
建表:
CREATE TABLE altercations ( instigator text, startedAt text, shipsDestroyed text, energyUsed text, allianceInvolvement text, PRIMARY KEY (instigator, startedAt, shipsDestroyed) );
?
查询:
SELECT * FROM altercations WHERE instigator='Jayne Cobb' AND startedAt = '7943-06-23' AND shipsDestroyed>'3' ORDER BY startedAt DESC;
?
.===============分隔符============================
问题:
?
后来,有添加了一个复合主键, 建表语句为:
CREATE TABLE altercations ( instigator text, startedAt text, shipsDestroyed text, energyUsed text, allianceInvolvement text, PRIMARY KEY (instigator, startedAt, shipsDestroyed, energyUsed) );
?查询语句:
SELECT * FROM altercations WHERE instigator='Jayne Cobb' AND startedAt = '7943-06-23' AND shipsDestroyed='3' AND energyUsed>'4.6' ORDER BY startedAt DESC;
?发现搜索出的结果完全混乱了,根本不是按条件查询出来的,如下:
?
instigator : Jayne Cobb; ?startedat : 7943-06-24; ?shipsdestroyed : 7; ?energyused : 4.6; ?allianceinvolvement : false; ?gender : null; ?
instigator : Jayne Cobb; ?startedat : 7943-06-24; ?shipsdestroyed : 6; ?energyused : 4.6; ?allianceinvolvement : false; ?gender : null; ?
instigator : Jayne Cobb; ?startedat : 7943-06-24; ?shipsdestroyed : 5; ?energyused : 4.6; ?allianceinvolvement : false; ?gender : null; ?
instigator : Jayne Cobb; ?startedat : 7943-06-