2013-08-12 3 views
0

J'ai essayé différentes approches, mais je ne peux pas trouver une solution à mon problème: Mes données est semblable à la table, ce qui signifie que j'ai un point de données (float) pour chaque combinaison d'entrées d'un ensemble de cordes:Cassandra: Quel schéma pour les mappages de type table?

(a mapping of S × S → ℝ) 

Je veux modéliser le schéma afin que je puisse faire les recherches suivantes:

  • toutes les paires de cordes avec une valeur dans une certaine gamme
  • pour une chaîne d'entrée donné, toutes les chaînes pour lesquelles la la valeur cartographiée est dans une certaine plage
  • pour une combinaison donnée d'entrée CORDES la valeur mappée

Depuis la mise en correspondance est symétrique (m(x,y) == m(y,x)), ce serait bien si je ne devais stocker les
n*(n+1)/2 valeurs uniques au lieu des n^2 applications au total.

Ce que j'ai essayé jusqu'à présent:

  1. S1 + » « + S2 comme une ligne de clé et la valeur en tant que nom de colonne
  2. S1 comme rangée et une clé composite de [S2: valeur] comme colonne nom
  3. S1 en tant que clé de ligne, S2 en tant que nom de colonne, valeur en tant que valeur de colonne.

mais malheureusement, toutes ces approches ne me permettent pas de faire toutes les requêtes dont j'ai besoin. Est-ce encore possible à Cassandra?

+0

Quelle est la taille de l'ensemble S? Et combien de valeurs uniques attendues? –

+0

S est d'environ 10000 articles pour le moment, mais je voudrais ajouter des familles de colonnes avec des ensembles plus grands (30k - 100k) plus tard. Pour les valeurs uniques: Elles sont toutes dans la plage [0,1], mais toutes les valeurs peuvent y figurer. – feob

Répondre

0

Cassandra ne supporte pas votre première requête --- toutes les paires de chaînes avec une valeur dans une certaine gamme --- depuis le moment, Cassandra ne permet que des requêtes de gamme avec au moins un EQ sur la clause WHERE.Cependant, votre deuxième et troisième requêtes est faisable :)


Exemple

Prenons l'exemple suivant:

cqlsh:so> desc table string_mappings; 
CREATE TABLE string_mappings (
    s1 ascii, 
    s2 ascii, 
    value float, 
    PRIMARY KEY (s1, s2, value) 
) 

et nous avons les tuples suivants:

cqlsh:so> select * from string_mappings; 

s1 | s2 | value 
-------+-------+------- 
hello | hello |  1 
hello | world | 0.2 
stack | hello |  0 
stack | stack |  1 
stack | world |  0 
world | world |  1 

Votre première requête ne fonctionne pas comme Cass andra pas actuellement en charge les requêtes portée sans EQ sur la clause WHERE:

cqlsh:so> select * from string_mappings where value>0.5; 
Bad Request: PRIMARY KEY part value cannot be restricted (preceding part s2 is either not restricted or by a non-EQ relation) 

Toutefois, la requête de plage suivante (votre deuxième requête) est très bien car il a une EQ:

cqlsh:so> select * from string_mappings where value > 0.5 and s2='hello' allow filtering; 

s1 | s2 | value 
-------+-------+------- 
hello | hello |  1 

et souvenez-vous mettre le mot-clé ALLOW FILTERING, ou vous obtiendrez l'erreur suivante:

cqlsh:so> select * from string_mappings where value > 0.5 and s2='hello'; 
Bad Request: Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING 

Enfin, votre troisième requête est als o pas de problème :)

cqlsh:so> select * from string_mappings where S1='hello' and S2='world'; 

s1 | s2 | value 
-------+-------+------- 
hello | world | 0.2 
+0

Merci beaucoup pour vos explications! Comme cql fait abstraction du modèle de données de cassandra sous-jacent, j'ai essayé votre schéma et il s'avère que cassandra crée une famille de colonnes exactement comme ma seconde tentative :) – feob

Questions connexes