我不知道如何使用 Astyanax 进行我需要的所有范围查询。我已经尝试过所解释的内容 这里 但它似乎不起作用。

仅供参考,我来自 Hector 世界,在那里我一切都运行良好,出于我不会解释的原因,我们决定切换到 Astyanax。

我有一个列族,描述如下。请注意“ReversedType”,它允许我们首先获得最新的 TimeUUID。它不应该影响其他人,至少对赫克托来说从来没有影响过:

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;
}

我曾经能够使用部分组合进行查询,如下所述 这里. 。我真正需要的是能够执行以下范围查询:

# 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 背景,我给出的复合材料(带注释的类)缺少 EQUALITY 参数。Code 3 不会完全满足我的需要,因为前缀适用于开始和结束,如果我想要,例如,从 (col1, timUUID1) 到 (col2, TimeUUID2) 的范围查询,这些前缀可能会有所不同。

我设法使 Range 4 轻松使用所有三个代码。

我设法使 Range 1 这样做可以使用所有三个代码:

  • Code 1 我给了 null 作为开始和结束的参数
  • Code 2 我避免调用 setStart 和 setEnd
  • Code 3 我避免调用 withPrefix 或任何相等方法。

我设法使 Range 2 只与 Code 3:

  • 我提供了 greaterThanEquals(columnStart.colname) 或者 lessThanEquals(columnStart.colname) 并且没有其他相等/前缀方法

我没能做到 Range 3 根本不。

显然,我只想使用 Code 1 因为我实际上不知道我将查询的列族。这里我只是使用一个复合列的示例,但它可能不是复合列或具有超过 2 个字段。

在赫克托,这真的很简单,我想要一些等价的:

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 进行部分复合。

感谢您的帮助。

有帮助吗?

解决方案

我无法使用上述方法完成我想做的所有事情,但我发现了第四种方法,尽管它不让我满意,但它有效。

我正在使用 ByteBuffer 的版本 withColumnRangeCode 1. 。开始和结束缓冲区是使用实际的 Composite 类构建的,如下所示:

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();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top