2013-07-15 34 views
10

如何使用CQL3引入一系列复合列?使用CQL3遍历Cassandra宽行

考虑以下几点:

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

在卡桑德拉什么这有效地作用是创建具有整数行的的ColumnFamily(的值)和与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值的同时。我该怎么做呢?这是我使用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麻烦?这是我的尝试:

​​

这不起作用,因为我们已经限制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 
+0

注意自己:[其他人有同样的问题](http://stackoverflow.com/q/16951532/348056)。 – JnBrymn

回答

5

自动分页做https://issues.apache.org/jira/browse/CASSANDRA-4415,它的发布卡桑德拉2.0.1

+4

为了我的理解,我已经安装了cassnadra 2.0.6和使用cqlsh我试图做一个选择查询CF(其中约20K记录)没有给予限制,我的查询结果是10K,并显示一条消息“**默认限制10000是使用。指定您自己的LIMIT子句以获得更多结果。**“..那么自动分页在哪里,或者是在做什么/理解错误。 – Shri

0

你试图做的是在卡桑德拉得到分页的东西。 CQL3不支持这一点。 您应该创建一个适合比较的列,即小于,大于操作,并且此列应该形成增加/减少的顺序。事实上,正如jorgebg在上面注意到的那样,b + c的连接会适合这一点。

4

通过阅读CQL3文档后,我还没有找到实现预期效果的方法。

但是,您可以通过一系列CQL查询来伪造所需的效果。考虑一下我想通过上述模型4中的项目进行分页。很容易得到第一个4:SELECT * FROM a = 1 LIMIT 4;

但是没有办法在单个查询中获得下4个。但我可以分段进行。从上面的查询中的最后一项是

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

这样我就可以发出一个查询,从这里开始,让一切直到b下一个值:

SELECT * FROM A = 1,其中B ='A '和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表(a.k.a Cassandra行)的扫描。


更新:事实上,CQL3没有一个服务器端游标,(见“CQL3分页”部分here),如果你想假的,你必须使用上述的东西(请阅读关于该链接的更多内容,以便看到我的基本思想由该文章的作者阐述)。

但是,有一个JIRA issue关于将在Cassandra 2中可用并且已经存在于Cassandra 2 Beta中的服务器端游标。

还有一个相关的JIRA issue,这将使我更容易实现客户端游标,因为我已经在上面暗示过了。但它没有解决。


更新2:JIRA issue现在已修复。

现在,您可以查询中使用元组/矢量语法WHERE(C1,C2)>(1,0)

+0

我不建议使用LIMIT子句。使用你的主键代替,也许在元表的帮助下。我经历了严重的性能下降,我认为这是由于分布式数据库的性质 - 因为它需要协调一致的努力来确定何时达到LIMIT,所以在返回结果集之前,必须统计所有行。 – omnibear

-1

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

+0

通常,如果答案包含对代码意图做什么的解释,以及为什么解决问题而不介绍其他问题,答案会更有帮助。 (这篇文章被至少一个用户标记,大概是因为他们认为没有解释的答案应该被删除。) –