سؤال

لا أستطيع معرفة كيفية إجراء جميع استعلامات النطاق التي أحتاجها باستخدام Astyanax.لقد حاولت ما هو موضح هنا ولكن لا يبدو أن العمل.

لمعلوماتك، أنا قادم من عالم هيكتور حيث عملت كل هذه الأمور بشكل جيد ولأسباب لن أشرحها، قررنا التحول إلى 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

إليك الطرق الثلاث التي جربتها:

# 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();

بناءً على خلفية هيكتور الخاصة بي، فإن المركب الذي أعطيه (الفصول المشروحة) يفتقد معلمة المساواة.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 لأنني في الواقع لا أعرف عائلة العمود التي سأقوم بالاستعلام عنها.أنا هنا أستخدم فقط مثالاً يحتوي على عمود مركب ولكنه قد لا يكون مركبًا أو يحتوي على أكثر من حقلين.

في هيكتور، الأمر بهذه السهولة حقًا وأريد ما يعادله:

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 beeing من أي نوع وإذا كان مركبًا، يسمح بالمركبات الجزئية مع تحديد المساواة في كل مكون.

شكرا لمساعدتك.

هل كانت مفيدة؟

المحلول

لم أتمكن من القيام بكل ما أردت باستخدام الطرق المذكورة أعلاه ولكني وجدت الطريقة الرابعة التي تعمل رغم أنها لا ترضيني.

أنا أستخدم 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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top