문제

Astyanax를 사용하여 필요한 모든 범위 쿼리를 만드는 방법을 알 수 없습니다.설명된 내용을 시도해 보았습니다. 여기 하지만 작동하지 않는 것 같습니다.

참고로 저는 이 모든 것이 잘 작동하는 Hector 세계에서 왔으며 설명할 수 없는 이유로 Astyanax로 전환하기로 결정했습니다.

다음과 같이 설명된 컬럼 패밀리가 있습니다.최신 TimeUUID를 먼저 가질 수 있는 "ReversedType"을 참고하세요.나머지 부분에는 영향을 주어서는 안 됩니다. 적어도 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;
}

설명된 대로 부분 복합을 사용하여 쿼리를 수행할 수 있었습니다. 여기.나에게 정말로 필요한 것은 다음과 같은 범위 쿼리를 수행할 수 있는 것입니다.

# 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 나는 Prefix나 동등 메서드를 사용하여 호출하는 것을 피했습니다.

나는 성공했다 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를 사용하여 부분 복합을 허용합니다.

당신의 도움을 주셔서 감사합니다.

도움이 되었습니까?

해결책

위의 방법을 사용하여 원하는 모든 작업을 수행할 수 없었지만 마음에 들지 않더라도 작동하는 네 번째 방법을 찾았습니다.

나는 ByteBuffer 버전 withColumnRange ~에 Code 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