查询有多个属性的Cassandra java BoundStatement

时间:2016-10-19 19:37:36

标签: java rest cassandra

我尝试使用BoundStatement的绑定方法从Cassandra获取记录,然后在其上执行session.execute。 假设json看起来如下所示

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

在这里,如果我想使用多个列(id = 1和name = abc)进行查询,我可以成功获取记录。

然而,我的json看起来像这样:

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

在数据库中,它会保存在两个不同的行中(因为有与name属性关联的值列表)

问题是如何从数据库中获取记录?

P.S.:id和名称是复合分区键

1 个答案:

答案 0 :(得分:1)

由于idname是复合分区键的一部分,因此您始终需要同时搜索它们。因此,您可以将您的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));