2012-09-05 1 views
4

Existe-t-il un moyen de répartir des lignes de requête avec une clé de ligne composite lors de l'utilisation d'un partitionnement aléatoire?Client Cassandra Hector: une requête RangeSlicesQuery sur des lignes composites est-elle possible lors de l'utilisation de Partitionnement aléatoire?

Im workling avec les familles de colonne créé par CQL v3 comme ceci:

CREATE TABLE products (rowkey CompositeType(UTF8Type,UTF8Type,UTF8Type,UTF8Type) 
PRIMARY KEY, prod_id varchar, class_id varchar, date varchar); 

Les données du tableau se présente comme suit:

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) 
------------------- 

J'essaie de trouver un moyen d'aller requête sur ces clés de ligne composites analogiques à la façon dont nous tranchons la requête sur les colonnes composites. L'approche suivante réussit parfois à rendre quelque chose d'utile en fonction de la touche de démarrage et d'arrêt que je choisis.

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); 

La plupart du temps la base retourne ceci:

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) 

Est-ce que quelqu'un a une idée si quelque chose comme cela peut être réalisé sans l'aide de l'ordre de préserver partitionneur? Dois-je créer un index de clé de ligne personnalisé pour ce cas d'utilisation?

Merci beaucoup!


Informations complémentaires:

Ce que je suis en train de faire est de stocker des données de transaction de vente dans une table qui utilise les deux touches de ligne composites pour encoder la date/heure/lieu et colonnes composites pour stocker des informations sur les articles vendus:

L'ensemble des articles par transaction est de taille variable et comprend des informations sur la taille, la couleur et la quantité de chaque élément:

{ ... 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 } , 
… ] } 

Il y a aussi des informations sur où et quand la transaction est arrivé incluant un identifiant unique de transaction:

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

Mon approche initiale était de mettre tous les éléments dans une ligne distincte et laissez les éléments du groupe d'application de retour ensemble par numéro de transaction. Cela fonctionne bien. Mais maintenant, je suis en train de tirer parti des capacités de structuration des colonnes composites pour conserver les données de l'élément imbriqué dans une représentation (par article) comme ceci:

item_id:’size’ = <value> ; item_id:’color’ = <value> ; item_id:’qty’ = <value> ; … 
43523:size = 050 ; 43523:color = 123 ; 43523:qty = 1 ; … 

Le reste des données sera codée dans une clé de ligne composite comme ceci:

date : time : store_id : trx_id 
20110303 : 0947 : 001 : 23324827346 

Je dois être en mesure d'exécuter des requêtes telles que: Tous les articles qui ont été vendus entre les dates 20110301 et 20110310 entre 1200 et 1400 fois dans les magasins 25 - 50. ce que j'atteint à ce jour avec des colonnes composites utilisait une rangée large par magasin et mettait tout le reste des données dans 3 colonnes composites différentes par article:

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 ; 

Cela fonctionne, mais cela ne semble pas très efficace. Y a-t-il d'autres alternatives?

Répondre

2

Vous créez une ligne par partition, donc il devrait être clair que RandomPartitioner ne vous donnera pas commandé des requêtes gamme.

Vous pouvez faire des plages commandées au sein de une partition, qui est très commun, par ex. http://rubyscale.com/blog/2011/03/06/basic-time-series-with-cassandra/ et http://www.datastax.com/dev/blog/advanced-time-series-with-cassandra

+0

Merci pour les liens! C'est ce que j'ai essayé jusqu'ici. Veuillez jeter un coup d'oeil aux ajouts que j'ai faits à ma question initiale. L'ordre des résultats n'est pas le problème, c'est plus sur l'InvalidRequestException ... Je dois admettre que je ne suis pas vraiment expert en fonctions de hachage. Donc, je dois juste accepter que la valeur de hachage d'une clé de ligne composite [ « 3: 3: 3: 3 »] est plus grand que [ « 6: 6: 6: 6 »]? Que je suppose que mon plan n'a pas d'avenir ... – maxbrenn

Questions connexes