2013-07-15 57 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

通常,如果答案包含對代碼意圖做什麼的解釋,以及爲什麼解決問題而不介紹其他問題,答案會更有幫助。 (這篇文章被至少一個用戶標記,大概是因爲他們認爲沒有解釋的答案應該被刪除。) –