Frage

Ich kann nicht herausfinden, wie ich mit Astyanax alle benötigten Bereichsabfragen durchführen kann.Ich habe versucht, was erklärt wurde Hier aber es scheint nicht zu funktionieren.

Zu Ihrer Information, ich komme aus der Hector-Welt, wo das alles gut funktioniert hat, und aus Gründen, die ich nicht erklären werde, haben wir uns entschieden, zu Astyanax zu wechseln.

Ich habe eine Spaltenfamilie, die wie folgt beschrieben wird.Beachten Sie den „ReversedType“, der es uns ermöglicht, zuerst die neueste TimeUUID zu haben.Es sollte keine Auswirkungen auf den Rest haben, zumindest war es bei Hector nie der Fall:

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))

Und hier ist die Definition als 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;
}

Ich bin in der Lage, wie beschrieben eine Abfrage mit Teilkompositen durchzuführen Hier.Was ich wirklich brauche, ist in der Lage zu sein, die folgenden Bereichsabfragen durchzuführen:

# 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

Hier sind die drei Möglichkeiten, die ich versucht habe:

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

Basierend auf meinem Hector-Hintergrund fehlt in der von mir angegebenen Zusammensetzung (annotierte Klassen) der EQUALITY-Parameter.Code 3 würde nicht genau das tun, was ich brauche, da das Präfix sowohl für den Anfang als auch für das Ende gilt und diese möglicherweise unterschiedlich sind, wenn ich beispielsweise die Abfrage von (col1, timUUID1) bis (col2, TimeUUID2) reichen möchte.

Ich habe es geschafft Range 4 Arbeiten Sie problemlos mit allen drei Codes.

Ich habe es geschafft Range 1 Arbeiten Sie mit allen drei Codes, indem Sie Folgendes tun:

  • In Code 1 Ich habe null als Parameter für Start und Ende angegeben
  • In Code 2 Ich habe es vermieden, setStart und setEnd aufzurufen
  • In Code 3 Ich habe es vermieden, withPrefix oder eine Gleichheitsmethode aufzurufen.

Ich habe es geschafft Range 2 nur mit arbeiten Code 3:

  • Ich habe beides bereitgestellt greaterThanEquals(columnStart.colname) oder lessThanEquals(columnStart.colname) und keine andere Gleichheits-/Präfixmethode

Ich habe es nicht geschafft Range 3 überhaupt.

Natürlich möchte ich nur verwenden Code 1 Da ich die Spaltenfamilie, die ich abfragen werde, eigentlich nicht kenne.Hier verwende ich nur ein Beispiel mit einer zusammengesetzten Spalte, die jedoch möglicherweise nicht zusammengesetzt ist oder mehr als zwei Felder enthält.

In Hector ist es wirklich so einfach und ich hätte gerne ein Äquivalent:

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

Dabei können colStart und colEnd einen beliebigen Typ haben und, wenn sie zusammengesetzt sind, teilweise zusammengesetzte Elemente mit einer für jede Komponente definierten Gleichheit zulassen.

Vielen Dank für Ihre Hilfe.

War es hilfreich?

Lösung

Ich konnte mit den oben genannten Methoden nicht alles erreichen, was ich wollte, aber ich habe eine vierte Methode gefunden, die funktioniert, auch wenn sie mir nicht gefällt.

Ich verwende das ByteBuffer Version von withColumnRange In Code 1.Der Start- und Endpuffer werden mithilfe der tatsächlichen Composite-Klasse wie folgt erstellt:

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();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top