2016-10-19 52 views
0

我試圖從Cassandra中使用BoundStatement的綁定方法獲取記錄,然後在其上執行session.execute。 假設JSON看起來像這樣如下圖所示關於具有多個屬性的Cassandra java BoundStatement的查詢

{ 
id:1, 
name:abc, 
. 
. 
. 
} 

在這裏,如果我想用多列查詢(ID = 1,名稱= ABC),我是能夠成功地獲取記錄。

然而,我的JSON看起來是這樣的:

{ 
id:1 
name:["abc","xyz"] 
. 
. 
. 
} 

在數據庫中,它被保存在兩個不同行(因爲有與name屬性相關聯的值的列表)

問題我如何從數據庫中獲取記錄?

P.S.:id和名稱是複合分區鍵

回答

1

由於idname是你永遠需要他們兩人的搜索複合分區鍵的一部分。所以你可以把你的JSON和名單列爲幾個選擇查詢或使用IN

推薦的解決方案

使用在同一時間兩個不同的SELECT查詢然後彙總這使得結果中的每個選擇打的最好節點假設你使用TokenAware。

我使用RxJava展開許多請求,然後將它們合併回行列表。

public class CassandraService { 
    //... 

    public void run() { 

    String id = "1"; 
    List<String> names = ['abc','xyz']; 


    PreparedStatement selectStmt = session.prepare("SELECT id, name, value FROM table WHERE id=? AND name=?;"); 
    List statements = new ArrayList<Statement>(); 

    for(String name : names) { 
     statements.add(selectStmt.bind(id,name)); 
    } 

    Observable<Row> rows = execute(statements); 

    //Do work with rows. 
    } 


    public Observable<ResultSet> executeAndReturnResultSet(Statement statement) { 
    return Observable.from(session.executeAsync(statement)); 
    } 


    public Observable<Row> execute(List<Statement> statements) { 
    List<Observable<ResultSet>> resultSets = Lists.transform(statements, this::executeAndReturnResultSet); 
    return Observable.merge(resultSets).flatMap(Observable::from); 
    } 
} 

替代

否則,你可以使用IN類似下面的CQL:

SELECT * FROM multi_partition_key WHERE id='1' AND name IN ('abc','xyz'); 

結合在Java驅動程序一份準備好的聲明。

String id = "1"; 
List<String> names = ['abc','xyz']; 

PreparedStatement sel = session.prepare("SELECT id, name, value FROM table WHERE id=? AND name IN ?;"); 
session.execute(sel.bind(id,name)); 
+0

感謝傑夫的快速響應。我搜索了互聯網,發現使用IN子句會降低性能。 – Sandy

+0

有沒有其他的選擇我們可以使用? – Sandy

+0

是的,在我的回答中,我推斷的方法是一次發送兩條select語句。 –