我无法弄清楚如何使用Astyanax进行我需要的所有范围查询。 我已经尝试了here所解释的内容,但它似乎没有用。
仅供参考我是从赫克托耳世界来的,我把这一切都搞定了,并且由于我不解释的原因,我们决定转而使用Astyanax。
我有一个列系列描述如下。请注意“ReversedType”,它允许我们首先拥有最新的TimeUUID。它不应该影响其余部分,因为它从未对Hector做过:
ColumnFamily: mycf
Key Validation Class: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.UTF8Type)
Default column value validator: org.apache.cassandra.db.marshal.UTF8Type
Columns sorted by: org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.TimeUUIDType))
这就是Astyanax CF的定义:
public static final CF = new ColumnFamily<Rowkey, Column>(
NAME,
new AnnotatedCompositeSerializer<Rowkey>(Rowkey.class),
new AnnotatedCompositeSerializer<Column>(Column.class),
StringSerializer.get()
);
public static class Column {
@Component(ordinal = 0)
public String colname = null;
@Component(ordinal = 1)
public UUID timeUUID = null;
}
public static class Rowkey {
@Component(ordinal = 0)
public String aid;
@Component(ordinal = 1)
public String cid;
}
我使用here描述的部分合成来进行查询。我真正需要的是能够进行以下范围查询:
# Range 1
# Should get the 10 first elements of the rowkey
colstart: null
colend: null
limit: 10
# Range 2
# Should get the 10 first elements of the rowkey
# that has as first part of the composite the string "mycol"
colstart: Column("mycol", null)
colend: Column("mycol", null)
limit: 10
# Range 3
# Should get the 10 first elements of the rowkey
# that has as first part of the composite the string "mycol"
# and with a timeuuid created with a timstamp between 'timestampStart' and 'timestampEnd'
colstart: Column("mycol", TimeUUID(timestampStart))
colend: Column("mycol", TimeUUID(timestampEnd))
limit: 10
# Range 4, not actually a range
# Should get the 1 column composed of "mycol" and existingTimeUUID
colstart: Column("mycol", existingTimeUUID)
colend: Column("mycol", existingTimeUUID)
limit: 10
以下是我试过的3种方法:
# Code 1
keyspace.prepareQuery(columnFamily)
.getKey(rowkey)
.withColumnRange(columnStart, columnEnd, false, 10)
.execute()
.getResult();
# Code 2
RangeBuilder rangeBuilder = new RangeBuilder()
.setStart(columnStart, CF.getColumnSerializer())
.setEnd(columnEnd, CF.getColumnSerializer())
.setReversed(false)
.setLimit(10);
keyspace.prepareQuery(columnFamily)
.getKey(rowkey)
.withColumnRange(rangeBuilder.build())
.execute()
.getResult();
# Code 3
CompositeRangeBuilder rangeBuilder = ((AnnotatedCompositeSerializer<Column>) colSerializer)
.buildRange()
.withPrefix(columnStart.colname)
.greaterThanEquals(columnStart.timeUUID)
.lessThanEquals(columnEnd.timeUUID)
.limit(10);
keyspace.prepareQuery(columnFamily)
.getKey(rowkey)
.withColumnRange(rangeBuilder.build())
.execute()
.getResult();
根据我的Hector背景,我给出的复合(Annotated Classes)错过了EQUALITY参数。
Code 3
不能完全满足我的需要,因为前缀适用于开始和结束,如果我想要的话,那些可能是不同的,从(col1,timUUID1)到(col2,TimeUUID2)的范围查询。
我设法让Range 4
轻松地使用所有三个代码。
通过这样做,我设法让Range 1
使用所有三个代码:
Code 1
中,我将null作为开始和结束的参数Code 2
我避免调用setStart和setEnd Code 3
中,我避免使用预览或任何相等的方法调用。我设法Range 2
仅使用Code 3
:
greaterThanEquals(columnStart.colname)
或lessThanEquals(columnStart.colname)
,没有提供其他相等/前缀方法我根本没有设法Range 3
。
很清楚,我只想使用Code 1
因为我实际上不知道我将要查询的列族。这里我只是使用复合列的示例,但它可能不是复合列或具有多于2个字段。
在hector中它真的很容易,我想要一些等价物:
MultigetSliceQuery<K, C, V> q = HFactory.createMultigetSliceQuery(connection.getKeyspace(), this.getRowKeySerializer(), this.getColumnNameSerializer(), this.getColumnValueSerializer());
q.setColumnFamily(this.getCfName());
q.setKeys(keys)
q.setRange(colStart, colEnd, reversed, count);
q.execute();
使用任何类型的colStart和colEnd,以及复合,允许在每个组件上定义了Equality的部分复合。
感谢您的帮助。
答案 0 :(得分:0)
我无法使用上述方法完成所有操作,但我找到了第4个,尽管它不能取悦我,但仍有效。
我正在ByteBuffer
中使用withColumnRange
Code 1
版本的public static <T> ByteBuffer toRangeStart(List<Object> list, boolean reversed) {
return toRangeValue(list, reversed ? ComponentEquality.GREATER_THAN_EQUAL : ComponentEquality.EQUAL);
}
public static <T> ByteBuffer toRangeEnd(List<Object> list, boolean reversed) {
return toRangeValue(list, reversed ? ComponentEquality.EQUAL : ComponentEquality.GREATER_THAN_EQUAL);
}
public static <T> ByteBuffer toRangeValue(List<Object> list, ComponentEquality eq) {
// We use a real composite as we didn't find any other way to build those ranges
Composite c = new Composite();
int i;
for (i = 0; i < list.size() - 1; i++) {
c.addComponent(list.get(i), SerializerTypeInferer.getSerializer(list.get(i)), ComponentEquality.EQUAL);
}
c.addComponent(list.get(i), SerializerTypeInferer.getSerializer(list.get(i)), eq);
return c.serialize();
}
。使用实际的Composite类构建开始和结束缓冲区,如下所示:
{{1}}