10

CQL3 で複合列の範囲を取り込むにはどうすればよいですか?

次の点を考慮してください。

CREATE TABLE Stuff (
    a int,
    b text,
    c text,
    d text,
    PRIMARY KEY (a,b,c)
);

Cassandra では、これが効果的に行うことは、整数行 (a の値) と、b と c の値およびリテラル文字列 'd' で構成される CompositeColumns を持つ ColumnFamily を作成することです。もちろん、これはすべて CQL3 によって隠蔽されているため、個々のデータベース行に挿入していると考えることができます... しかし、余談です。

そして、次の一連の入力を検討してください。

INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','P','whatever0');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','Q','whatever1');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','R','whatever2');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','S','whatever3');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','T','whatever4');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','P','whatever5');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','Q','whatever6');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','R','whatever7');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','S','whatever8');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','T','whatever9');

私の現在のユース ケースでは、Stuff のすべての値を一度に読み取りたいと考えてnいます。どうすればいいですか?を使用した現在のテイクは次のn=4とおりです。

SELECT * FROM Stuff WHERE a=1 LIMIT 4;

そして、予想どおり、次のようになります。

 a | b | c | d
---+---+---+-----------
 1 | A | P | whatever0
 1 | A | Q | whatever1
 1 | A | R | whatever2
 1 | A | S | whatever3

私が遭遇する問題は、次の 4 をどのように取得するかです。これが私の試みです:

SELECT * FROM Stuff WHERE a=1 AND b='A' AND c>'S' LIMIT 4;

これは、b を 'A' に等しくなるように制約しているため機能しません。これは妥当なことです。しかし、とにかく反復を続けることを可能にする CQL3 構文には何も見つかりませんでした。次のようなことができたらいいのにと思います:

SELECT * FROM Stuff WHERE a=1 AND {b,c} > {'A','S'} LIMIT 4;

希望する結果を得るにはどうすればよいですか。つまり、CQL3を返すにはどうすればよいですか:

 a | b | c | d
---+---+---+-----------
 1 | A | T | whatever0
 1 | B | P | whatever1
 1 | B | Q | whatever2
 1 | B | R | whatever3
4

4 に答える 4

5

自動ページングが行われます https://issues.apache.org/jira/browse/CASSANDRA-4415、Cassandra 2.0.1 へのリリースです

于 2013-11-08T00:45:21.197 に答える
4

CQL3 ドキュメントを読んだ後、目的の効果を達成する方法が見つかりませんでした。

ただし、一連の CQL クエリを使用して目的の効果を偽造することはできます。上記のモデル 4 のアイテムを一度にページングしたいとします。最初の 4 つを取得するのは簡単です。

SELECT * FROM a = 1 LIMIT 4;

ただし、1 回のクエリで次の 4 を取得する方法はありません。しかし、私はそれを断片的に行うことができます。上記のクエリの最後の項目は

 a | b | c | d
---+---+---+-----------
 1 | A | S | whatever3

したがって、ここから開始するクエリを発行して、 の次の値まですべてを取得できますb

SELECT * FROM a = 1 WHERE b='A' and c>'S' LIMIT 4;

この場合、単一の CQL3 行を取得します。

 a | b | c | d
---+---+---+-----------
 1 | A | T | whatever4

(ここで、4 つの行を取得した場合、制限に達し、次回はそのセットの最後の要素からやり直すことになります。しかし、今のところ、1 つの行しかありません。)そのポイントと残りの 3 行を取得します。

SELECT * FROM a = 1 WHERE b > 'A' LIMIT 3;

そして、好きなだけインクリメンタルにスキャンするまで、この同じアルゴリズムを続けます。

上記の例では、PRIMARY KEY は 3 つの要素で構成されており、Cassandra の CQL では列名が 2 つの要素の CompositeColumns であることを意味します (基本的には、違いはここでは問題になりません)。CompositeColumns は 2 つの要素であるため、ここでデモしたように 2 つのクエリを作成する必要があります。一般に、PRIMARY KEY がn要素の場合、n-1クエリを作成して CQL テーブル (別名 Cassandra 行) のスキャンを偽造する必要があります。


更新: 実際、CQL3 にはサーバー側カーソルがありません (ここの「CQL3 ページネーション」セクションを参照してください)。それを偽造したい場合は、上記の何かを使用する必要があります (そのリンクについて詳しく読むので、私の基本的なアイデアは、投稿の著者によって詳述されています)。

ただし、Cassandra 2 で使用可能になり、Cassandra 2 Beta に既に存在するサーバー側カーソルに関するJIRA の問題があります。

上記で示唆したように、クライアント側カーソルの実装をはるかに簡単にする、関連するJIRA の問題もあります。しかし、それは未解決のままです。


Update2: JIRA の問題が修正されました。

タプル/ベクター構文 WHERE (c1, c2) > (1, 0) を使用してクエリを実行できるようになりました

于 2013-07-16T18:33:43.393 に答える
-1

select * from stuff where a = 1 and (b,c) > ('A','S') limit 4;

于 2015-05-26T19:33:24.123 に答える