Клиент Cassandra Hector: возможен ли RangeSlicesQuery на составных ключах строк при использовании случайного разбиения?

Есть ли способ ранжировать строки запроса с составным ключом строки при использовании случайного секционирования?

Я работаю с семействами столбцов, созданными с помощью 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 } ,
… ] }

Также есть информация о том, где и когда произошла транзакция, включая уникальный идентификатор транзакции:

{ trx_id : 23324827346, store_id : 8934 , date : 20110303 , time : 0947 , …

Мой первоначальный подход заключался в том, чтобы поместить каждый элемент в отдельную строку и позволить приложению группировать элементы вместе по идентификатору транзакции. Это работает нормально. Но теперь я пытаюсь использовать возможности структурирования составных столбцов для сохранения данных вложенных элементов в представлении (для каждого элемента) следующим образом:

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 между 12:00 и 14:00 в магазинах 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 ;

Работает, но не очень эффективно. Есть ли другая альтернатива?


person maxbrenn    schedule 05.09.2012    source источник


Ответы (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

person jbellis    schedule 06.09.2012
comment
Спасибо за ссылки! Это то, что я пробовал до сих пор. Пожалуйста, взгляните на дополнения, которые я сделал к моему первоначальному вопросу. Проблема не в упорядочении результатов, а в InvalidRequestException… Должен признаться, я не эксперт в хеш-функциях. Так что мне просто нужно признать, что хешированное значение составного ключа строки [‘3:3:3:3’] больше, чем [‘6:6:6:6’]? Тогда я думаю, что у моего плана нет будущего ... - person maxbrenn; 06.09.2012