使用随机分区时,有没有办法用复合行键来查询行?
我正在处理通过CQL v3创建的列族,如下所示:
CREATE TABLE products ( rowkey CompositeType(UTF8Type,UTF8Type,UTF8Type,UTF8Type)
PRIMARY KEY, prod_id varchar, class_id varchar, date varchar);
表中的数据如下所示:
RowKey: 6:3:2:19
=> (column=class_id, value=254, timestamp=1346800102625002)
=> (column=date, value=2034, timestamp=1346800102625000)
=> (column=prod_id, value=1922, timestamp=1346800102625001)
-------------------
RowKey: 0:14:1:16
=> (column=class_id, value=144, timestamp=1346797896819002)
=> (column=date, value=234, timestamp=1346797896819000)
=> (column=prod_id, value=4322, timestamp=1346797896819001)
-------------------
我试图找到一种方法来对这些复合行键进行范围查询,类似于我们如何对复合列进行切片查询.以下方法有时实际上会成功返回一些有用的东西,具体取决于我选择的开始和停止键.
Composite startKey = new Composite();
startKey.addComponent(0, "3", Composite.ComponentEquality.EQUAL);
startKey.addComponent(1, "3", Composite.ComponentEquality.EQUAL);
startKey.addComponent(2, "3", Composite.ComponentEquality.EQUAL);
startKey.addComponent(3, "3", Composite.ComponentEquality.EQUAL);
Composite stopKey = new Composite();
stopKey.addComponent(0, "6", Composite.ComponentEquality.EQUAL);
stopKey.addComponent(1, "6", Composite.ComponentEquality.EQUAL);
stopKey.addComponent(2, "6", Composite.ComponentEquality.EQUAL);
stopKey.addComponent(3, "6" , Composite.ComponentEquality.GREATER_THAN_EQUAL);
RangeSlicesQuery<Composite, String, String> rangeSlicesQuery =
HFactory.createRangeSlicesQuery(keyspace, CompositeSerializer.get(), StringSerializer.get(), StringSerializer.get());
rangeSlicesQuery.setColumnFamily(columnFamilyName);
rangeSlicesQuery.setKeys(startKey,stopKey);
rangeSlicesQuery.setRange("", "", false, 3);
大多数情况下,数据库返回此信息:
InvalidRequestException(why:start key's md5 sorts after end key's md5.
this is not allowed; you probably should not specify end key at all,
under RandomPartitioner)
有人知道如果没有使用订单保留分区程序可以实现这样的事情吗?我是否必须为此用例构建自定义行键索引?
非常感谢!
附加信息:
我要做的是将销售交易数据存储在一个表中,该表使用复合行键来编码日期/时间/地点和复合列来存储有关已售物品的信息:
每笔交易的项目集大小不一,包括有关每个项目的大小,颜色和数量的信息:
{ ... items :
[ { item_id : 43523 , size : 050 , color : 123 , qty : 1 } ,
{ item_id : 64233 , size : 048 , color : 834 , qty : 1 } ,
{ item_id : 23984 , size : 000 , color : 341 , qty : 3 } ,
… ] }
还有关于交易发生的地点和时间的信息,包括唯一的交易ID:
{ trx_id : 23324827346, store_id : 8934 , date : 20110303 , time : 0947 , …
我最初的方法是将每个项目放在一个单独的行中,然后通过事务ID将应用程序组项目重新组合在一起.这工作正常.但是现在我正在尝试利用复合列的结构化功能来将嵌套项数据保存在表示形式(每个项目)中,如下所示:
item_id:’size’ = <value> ; item_id:’color’ = <value> ; item_id:’qty’ = <value> ; …
43523:size = 050 ; 43523:color = 123 ; 43523:qty = 1 ; …
其余数据将以复合行键编码,如下所示:
date : time : store_id : trx_id
20110303 : 0947 : 001 : 23324827346
我需要能够运行以下查询:所有在20110301和20110310之间在商店25到50之间在1200到1400之间出售的商品.到目前为止,我使用复合列实现的是每个商店使用一个宽行并放入所有商品其余数据为每个项目3个不同的复合列:
date:time:<type>:prod_id:transaction_id = <value> ; …
20110303:0947:size:43523:23324827346 = 050 ;
20110303:0947:color:43523:23324827346 = 123 ;
20110303:0947:qty:43523:23324827346 = 1 ;
它工作正常,但它看起来并不高效.
还有其他选择吗?
最佳答案 您正在为每个分区创建一行,因此应该清楚RandomPartitioner不会为您提供有序范围查询.
您可以在分区内执行有序范围,这很常见,例如http://rubyscale.com/blog/2011/03/06/basic-time-series-with-cassandra/和http://www.datastax.com/dev/blog/advanced-time-series-with-cassandra