我尝试使用BoundStatement的绑定方法从Cassandra获取记录,然后在其上执行session.execute。 假设json看起来如下所示
{
id:1,
name:abc,
.
.
.
}
在这里,如果我想使用多个列(id = 1和name = abc)进行查询,我可以成功获取记录。
然而,我的json看起来像这样:
{
id:1
name:["abc","xyz"]
.
.
.
}
在数据库中,它会保存在两个不同的行中(因为有与name属性关联的值列表)
问题是如何从数据库中获取记录?
P.S.:id和名称是复合分区键
答案 0 :(得分:1)
由于id
和name
是复合分区键的一部分,因此您始终需要同时搜索它们。因此,您可以将您的JSON和名单列出一些选择查询或使用IN
。
推荐的解决方案
同时使用两个不同的SELECT查询然后聚合结果,这允许每个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);
}
}
<强>替代强>
否则您可以像以下CQL一样使用IN
:
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));