4

使用随机分区时,有没有办法使用复合行键来范围查询行?

我正在使用通过 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 之间在 1200 和 1400 之间在 25 - 50 号商店中销售的所有商品。到目前为止,我使用复合列实现的是每家商店使用一个宽行并将所有其余数据为每个项目 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 ;

它正在工作,但看起来效率并不高。还有其他选择吗?

4

1 回答 1

2

您正在为每个分区创建一行,因此应该清楚 RandomPartitioner 不会为您提供有序范围查询。

您可以一个分区内执行有序范围,这很常见,例如http://rubyscale.com/blog/2011/03/06/basic-time-series-with-cassandra/http://www.datastax。 com/dev/blog/advanced-time-series-with-cassandra

于 2012-09-06T14:13:10.537 回答