2015-09-30 2 views
2

J'ai une table d'alertes. Je veux interroger dessus en utilisant l'opérateur IN sur 2 colonnes et en utilisant l'opérateur plus grand que sur une colonne. J'ai essayé les choses ci-dessous sans aucune chance. Quelqu'un peut-il me dire s'il vous plaît le design DB pour faire fonctionner la requête? Mes détails d'environnement: [cqlsh 5.0.1 | Cassandra 2.1.2 | Spécification CQL 3.2.0 | protocole natif v3]Utilisation de l'opérateur IN dans CQL sur la clé de partition et (clé de clustering ou colonne indexée)

Avec 'type' dans la clé de partition:

CREATE TABLE alerts (
    serialNumber text, 
    time bigint, 
    type text, 
    time2 int, 
    status text, 
    parentId int, 
    PRIMARY KEY ((serialNumber,type), time) 
) WITH CLUSTERING ORDER BY (time DESC); 

cqlsh:testdb> select * from alerts WHERE serialNumber IN ('1','2') AND type IN ('1','2','3') AND time > 1; 
code=2200 [Invalid query] message="Partition KEY part serialNumber cannot be restricted by IN relation (only the last part of the partition key can)" 

Avec 'type' dans la clé de clustering:

CREATE TABLE alerts (
    serialNumber text, 
    time bigint, 
    type text, 
    time2 int, 
    status text, 
    parentId int, 
    PRIMARY KEY (serialNumber, type, time) 
) WITH CLUSTERING ORDER BY (type ASC,time DESC); 

cqlsh:testdb> select * from alerts WHERE serialnumber IN ('1','2') AND type IN ('a','b') and time > 1; 
code=2200 [Invalid query] message="Clustering column "type" cannot be restricted by an IN relation" 

Avec index du type:

CREATE TABLE alerts (
    serialNumber text, 
    time bigint, 
    type text, 
    time2 int, 
    status text, 
    parentId int, 
    PRIMARY KEY (serialNumber, time) 
) WITH CLUSTERING ORDER BY (time DESC); 
CREATE INDEX alertsTypeIndex ON alerts(type); 

select * from alerts WHERE serialnumber IN ('1','2') and time > 1 AND type IN ('a','b'); 
code=2200 [Invalid query] message="IN predicates on non-primary-key columns (type) is not yet supported" 

select * from alerts WHERE serialnumber IN ('1','2') and time > 1 AND type = 'a'; 
code=2200 [Invalid query] message="Select on indexed columns and with IN clause for the PRIMARY KEY are not supported" 

Répondre

1

Quelle version êtes-vous? Votre deuxième exemple a fonctionné pour moi en 2.2.1:

Connected to VaporTrails at 127.0.0.1:9042. 
[cqlsh 5.0.1 | Cassandra 2.2.1 | CQL spec 3.3.0 | Native protocol v4] 
Use HELP for help. 
[email protected]> use stackoverflow ; 
[email protected]:stackoverflow> CREATE TABLE alerts (
       ...  serialNumber text, 
       ...  time bigint, 
       ...  type text, 
       ...  time2 int, 
       ...  status text, 
       ...  parentId int, 
       ...  PRIMARY KEY (serialNumber, type, time) 
       ...) WITH CLUSTERING ORDER BY (type ASC,time DESC); 
[email protected]:stackoverflow> INSERT INTO alerts (serialnumber , time,type,time2, status, parentid) VALUES ('1',0,'1',1,'1',1); 
[email protected]:stackoverflow> INSERT INTO alerts (serialnumber , time,type,time2, status, parentid) VALUES ('2',2,'2',2,'2',2); 
[email protected]:stackoverflow> INSERT INTO alerts (serialnumber , time,type,time2, status, parentid) VALUES ('3',3,'3',3,'3',3); 
[email protected]:stackoverflow> select * from alerts WHERE serialNumber IN ('1','2') AND type IN ('1','2','3') AND time > 1; 

serialnumber | type | time | parentid | status | time2 
--------------+------+------+----------+--------+------- 
      2 | 2 | 2 |  2 |  2 |  2 

(1 rows) 

Même si vous pouvez l'obtenir pour travailler, je vais recommander contre il. L'utilisation du mot clé IN sur une clé de partition est connue sous le nom d'anti-pattern "multi-clé". DataStax a un blurb in their documentation discussing why this is bad. Essentiellement, cette approche n'est pas mise à l'échelle car de nombreux nœuds doivent être interrogés pour satisfaire ces types de requêtes. Vous devriez trouver un autre moyen de modéliser vos alertes de sorte que vous n'ayez pas besoin d'utiliser une relation IN.

+1

Merci @Aaron. J'utilise 2.1.2. Serez-vous possible de proposer un nouveau modèle pour mes alertes? –