10

如何使用 CQL3 拉入一系列复合列?

考虑以下:

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

在 Cassandra 中,这有效地创建了一个 ColumnFamily,其中包含整数行(a 的值)以及由 b 和 c 的值以及文字字符串“d”组成的 CompositeColumns。当然,这一切都被 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');

在我当前的用例中,我想n一次读取 Stuff 的所有值。我该怎么做呢?这是我目前的使用方法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 限制 4;

但是,没有办法在单个查询中获得下一个 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 行,我会达到极限,下次我会从该集合的最后一个元素重新开始。但现在我只有一行。)所以,为了得到其余的我迭代一点并获得剩余的 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 分页”部分),如果您想伪造它,您必须使用上述内容(进一步阅读该链接,请参阅我的基本想法由帖子作者阐述)。

但是,关于服务器端游标存在JIRA 问题,该游标将在 Cassandra 2 中可用,并且在 Cassandra 2 Beta 中已经存在。

正如我在上面所暗示的,还有一个相关的JIRA 问题可以更容易地实现客户端游标。但它悬而未决。


更新 2:JIRA 问题现已修复。

您现在可以使用元组/向量语法查询 WHERE (c1, c2) > (1, 0)

于 2013-07-16T18:33:43.393 回答
0

您尝试做的是在 Cassandra 中获取分页内容。CQL3 不支持这一点。您应该创建一个适合比较的列,即小于、大于操作,并且该列应形成递增/递减序列。事实上,正如 jorgebg 上面注意到的那样,b+c 的串联很适合这个。

于 2013-07-16T14:25:12.927 回答
-1

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

于 2015-05-26T19:33:24.123 回答