2012-08-06 4 views
3

Salut je veux insérer dans ce genre de ligne de famille de colonne avec clé composite:Hector - Insérer une ligne avec clé composite

CREATE TABLE my_items (
user_id uuid, 
item_id uuid, 
description varchar, 
PRIMARY KEY (user_id, item_id)); 

J'essayez ceci:

StringSerializer stringSerializer = StringSerializer.get(); 
    UUIDSerializer uuidSerializer = UUIDSerializer.get(); 
    CompositeSerializer compositeSerializer = CompositeSerializer.get(); 

    HColumn<String, UUID> hColumnObj_userID = HFactory.createColumn("user_id", userID, stringSerializer, uuidSerializer); 
    HColumn<String, UUID> hColumnObj_itemID= HFactory.createColumn("item_id", itemID, stringSerializer, uuidSerializer); 

    Mutator<Composite> mutator = HFactory.createMutator(
      repository.getKeyspace(), 
      compositeSerializer); 
    Composite colKey = new Composite(); 
    colKey.addComponent(userID, uuidSerializer); 
    colKey.addComponent(itemID, uuidSerializer); 

    mutator.addInsertion(colKey, 
      "my_items", hColumnObj_userID); 
    mutator.addInsertion(colKey, 
      "my_items", hColumnObj_itemID); 

    mutator.execute(); 

Quel est le problème avec le code ci-dessus ? Je continue d'obtenir cette erreur: "InvalidRequestException (pourquoi: les UUID doivent être exactement 16 octets)". Et comment puis-je insérer des données dans la famille de colonnes que je décris ci-dessus.

Vive

+0

Comment sont des variables user_id et ITEM_ID déclarés? –

+0

Il est déclaré en tant que type UUID. – ShP

Répondre

7

On dirait que Hector attendait un composé contenant un UUID et une chaîne et trouvé seulement une chaîne. Avant d'écrire le code Hector, vous devez traduire le DDL créé dans le modèle de stockage utilisé par CQL. Dans ce cas, même si vous avez deux clés primaires, seul le premier, user_id, est utilisé comme clé de ligne. C'est toujours le cas. Toutes les autres clés primaires (item_id dans ce cas) sont utilisées pour former des noms de colonnes composites pour chaque colonne à l'exception de la première clé primaire. Cela signifie que lorsque vous utilisez Hector pour votre famille de colonnes my_items, vous devez écrire deux colonnes, une pour item_ID et une pour la description.

Le nom de la colonne pour la valeur item_id est un composite composé des valeurs des clés primaires 2 ... n (item_id dans cet exemple) et un nom de chaîne constant de la valeur ("item_id").

Le nom de la colonne pour la valeur de description est également un composite de la valeur item_id et du nom de la valeur ("description"). Si vous avez écrit 3 lignes de table CQL, chacune avec le même id_utilisateur mais avec des valeurs item_id différentes, vous vous retrouveriez avec une seule ligne de colonne dont la clé de ligne est la valeur commune user_id et qui a 6 colonnes, un item_id colonne et une colonne de description pour chacune des 3 lignes de la table CQL.

Le code devrait ressembler à ceci:

import java.util.UUID; 

import me.prettyprint.cassandra.serializers.CompositeSerializer; 
import me.prettyprint.cassandra.serializers.IntegerSerializer; 
import me.prettyprint.cassandra.serializers.StringSerializer; 
import me.prettyprint.cassandra.serializers.UUIDSerializer; 
import me.prettyprint.hector.api.Keyspace; 
import me.prettyprint.hector.api.beans.Composite; 
import me.prettyprint.hector.api.beans.HColumn; 
import me.prettyprint.hector.api.beans.AbstractComposite.ComponentEquality; 
import me.prettyprint.hector.api.factory.HFactory; 
import me.prettyprint.hector.api.mutation.Mutator; 

    // put this here to make it compile cleanly 

    Keyspace keyspace = null; 
    UUID userID = null; 
    UUID itemID = null; 
    String description = null; 

      // Row key is user_id of type UUID 

    Mutator<UUID> mutator = HFactory.createMutator(
      keyspace, 
      UUIDSerializer.get()); 

     // write column for itemID. 
     // Column name is composite of itemID value and constant "item_id" 
     // Row key is value of userID 

    Composite itemIdColumnName = new Composite(); 
    itemIdColumnName.addComponent(itemID , UUIDSerializer.get()); 
    itemIdColumnName.addComponent("item_id" , StringSerializer.get()); 
     // HFactory.createColumn takes args: column name, column value, serializer for column name, serializer for column value 
    HColumn<Composite, UUID> hColumnObj_itemID = HFactory.createColumn(itemIdColumnName, userID, new CompositeSerializer(), UUIDSerializer.get()); 
    mutator.addInsertion(userID, "my_items", hColumnObj_itemID); 

    // write column for description. 
    // Column name is composite of itemID value and constant "description" 
    // Row key is value of userID 

    Composite descriptionColumnName = new Composite(); 
    itemIdColumnName.addComponent(itemID , UUIDSerializer.get()); 
    itemIdColumnName.addComponent("description" , StringSerializer.get()); 
    HColumn<Composite, String> hColumnObj_description = HFactory.createColumn(descriptionColumnName, description , new CompositeSerializer(), StringSerializer.get()); 
    mutator.addInsertion(userID, "my_items", hColumnObj_description); 

    mutator.execute(); 
+0

Hm, mais quelle est la différence entre une clé composite et une colonne composite? Il semble que je peux réaliser la même chose en utilisant des colonnes composites. Il semble que le terme "clé de composition" dans cassandra/hector ne soit pas vraiment une clé composite comme dans SGBDR. BTW, je vais vérifier ce code dès que je vais travailler et je vous ferai connaître les résultats. ;) – ShP

+0

La terminologie est un peu confuse. Le CREATE TABLE affiche deux clés primaires, mais cela n'implique pas que la clé de ligne est un objet composite. Au contraire, la clé de ligne est toujours la première clé primaire et toutes les autres clés primaires, si elles sont spécifiées, sont utilisées pour créer des noms de colonnes composites pour contenir les valeurs de toutes les colonnes CQL nommées dans le DDL. –

+0

Ok, merci pour la clarification. Je vais vérifier le code un peu plus tard, mais je suppose que cela devrait fonctionner. Je vous remercie. Vladica – ShP

Questions connexes