是否可以使用Hector或Astyanax通过复合键获取行(在多列中,而不是序列化为一列的那些)?
在cqlsh中我创建了简单的列族:
CREATE COLUMNFAMILY kkvv (x int, y int, val1 varchar, val2 varchar, PRIMARY KEY (x,y));
根据Cassandra Developer Center,行按x存储为键,其余行存储在列中。
我无法确定如何为给定的x和y获取列切片。
在hector中执行cql的cql
cqlQuery.setQuery("select * from kkvv")
给我行:
行(2,ColumnSlice([HColumn(X = 2)]))
行(10,ColumnSlice([HColumn(X = 10)]))
和控制台cqlsh给出:
x | y | val1 | val2的
---- + ----- + ------- + -----------
2 | 1 | v1_1 | v2_1
10 | 27 | v1_4b | v2_4b
10 | 91 | v1_4a | v2_4a
任何人都设法在任何cassandra客户端中为java做到这一点? 我可以使用thrift,或者它只是cql功能吗?
答案 0 :(得分:0)
这里有两种不同的语法:CQL 2和CQL 3.默认情况下,Cassandra连接需要CQL 2.但是,CQL 2不能理解你在这里做的那种复合键列系列
所以你显然正确地使用CQL 3和cqlsh,因为它以一种理智的方式显示你的列,但是你没有将它与Hector一起使用。我不确定Hector或Astyanax是否支持这一点。最新版本的cassandra-jdbc驱动程序确实如此,如果Hector和/或Astyanax使用它,那么它们也应该工作。
在Thrift中没有(也可能不会)支持复合比较器列系列作为具有多组件主键的表,CQL 3的方式。如果需要,请使用CQL 3.
答案 1 :(得分:0)
您是否尝试过cassandra-tutorial项目中提供的CompositeQuery.java示例?
另外,您是否阅读了DataStax的Introduction to Composite Columns?
答案 2 :(得分:0)
很好地解释了如何在Cassandra中存储具有复合键的行here。
在Astyanax和Hector中,我注意到有趣的事情 - 当试图连接时 - 它使用了CQL2。当我使用带有cassandra api的CQL3连接到Cassandra(来自示例下面的代码)时,某处存储了此设置,之后Astyanax和Hector使用了cql3而不是CQL2。连接是作为单独的执行进行的,因此它无法存储在客户端......有人对此有任何想法吗?
可以使用set_cql_version方法在org.apache.cassandra.thrift.Cassandra.Client上设置CQL版本。
如果有人对使用纯Cassandra api的工作示例感兴趣:
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.List;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.Compression;
import org.apache.cassandra.thrift.CqlResult;
import org.apache.cassandra.thrift.CqlRow;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.SchemaDisagreementException;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
public class KKVVGetter {
private static Cassandra.Client client;
private static TTransport transport;
public static void main(String[] args) throws UnsupportedEncodingException, InvalidRequestException,
UnavailableException, TimedOutException, SchemaDisagreementException, TException {
transport = new TFramedTransport(new TSocket("localhost", 9160));
TProtocol protocol = new TBinaryProtocol(transport);
client = new Cassandra.Client(protocol);
transport.open();
client.set_cql_version("3.0.0");
executeQuery("USE ks_test3");
show("select x,y,val1,val2 from kkvv where x > 1 and x < 11 and y < 100 and y > 2");
System.out.println("\n\n*****************************\n\n");
show("select x,y,val1,val2 from kkvv");
transport.close();
}
private static int toInt(byte[] bytes) {
int result = 0;
for (int i = 0; i < 4; i++) {
result = (result << 4) + (int) bytes[i];
}
return result;
}
private static CqlResult executeQuery(String query) throws UnsupportedEncodingException, InvalidRequestException,
UnavailableException, TimedOutException, SchemaDisagreementException, TException {
return client.execute_cql_query(ByteBuffer.wrap(query.getBytes("UTF-8")), Compression.NONE);
}
private static void show(String query) throws UnsupportedEncodingException, InvalidRequestException,
UnavailableException, TimedOutException, SchemaDisagreementException, TException {
CqlResult result = executeQuery(query);
List<CqlRow> rows = result.getRows();
System.out.println("rows: " + rows.size());
for (CqlRow row : rows) {
System.out.println("columns: " + row.getColumnsSize());
for (Column c : row.getColumns()) {
System.out.print(" " + new String(c.getName()));
switch (new String(c.getName())) {
case "x":
case "y":
System.out.print(" " + toInt(c.getValue()));
break;
case "val1":
case "val2":
System.out.print(" " + new String(c.getValue()));
break;
default:
break;
}
System.out.println();
}
}
}
}
有问题的架构示例。