Диапазон Accumulo - ключ конца не включен - PullRequest
0 голосов
/ 13 ноября 2018

Я изучаю Accumulo и, похоже, не могу получить ключ конца, указанный в диапазоне, включающим.Мой код ниже.Я попытался явно установить endKeyInclusive в true в Range, но это не помогло.

BatchWriter writer = conn.createBatchWriter("table", config);

List<String> deterTimes = new ArrayList<>();

String rowId = "3015551212<ll>";
String columnFamily = "deter";
for (int i = 0; i < 10; i++) {
    String deterTime = "20181112:21:46:33" + i;
    deterTimes.add(deterTime);
    writer.addMutation(makeRecord(rowId, columnFamily, deterTime, "DETER" + i));                   
}

writer.flush();
writer.close();

Scanner scan = conn.createScanner("table", auths);

Key startKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(1).getBytes());
Key endKey = new Key(rowId.getBytes(), columnFamily.getBytes(), deterTimes.get(4).getBytes());
Range range = new Range(startKey, endKey);
if (range.isEndKeyInclusive())  System.out.println("true");
scan.setRange(range);

for (Entry<Key,Value> entry : scan) {
    Text row = entry.getKey().getRow();
    Text cq = entry.getKey().getColumnQualifier();
    Value value = entry.getValue();
    System.out.println("Fetched row " + row + " with value: " + value + ", cq=" + cq);
}

Вывод:

true
Fetched row 3015551212<ll> with value: DETER1, cq='20181112:21:46:331'
Fetched row 3015551212<ll> with value: DETER2, cq='20181112:21:46:332'
Fetched row 3015551212<ll> with value: DETER3, cq='20181112:21:46:333'

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Вы создаете свой конечный ключ с ( row, column family, column qualifier ) в качестве байтовых массивов, а оставшиеся измерения ключа ( column visibility, timestamp ) устанавливаются в значения по умолчанию (в частности, пустой байтовый массив и Long.MAX_VALUE соответственно).

Сканер остановится на этом точном ключе включительно.Однако фактический ввод данных почти наверняка не является ключом , точным (вы не предоставили свою реализацию makeRecord для проверки).Даже если ваши данные на самом деле имеют видимость пустого столбца, отметка времени почти наверняка будет не Long.MAX_VALUE, а скорее чем-то, что вы установили в своей реализации makeRecord, или она была установлена ​​на основе времени сервера или какого-то логического счетчика таблицы.Поскольку размер временной метки ключа упорядочен по убыванию, ваш сканер прекратит поиск данных на Long.MAX_LONG, прежде чем он достигнет ваших записей.

Это немного похоже на поиск в словаре для analogy, но останавливается, когдавы достигнете analog: пропустите оставшиеся слова, начинающиеся с analog.

Это распространенная ошибка при построении диапазонов на основе точных ключей.Как правило, лучше создавать диапазоны на основе строк (включая строки, включающие всю строку), а не ключей (для этого есть конструктор Range ).Или указать конечный ключ, чтобы он работал исключительно.Вы можете сделать это, добавив нулевой байт в конец вашего последнего значащего элемента столбца.Например, вы можете сделать что-то вроде:

Key endKey = new Key(rowId.getBytes(),
                     columnFamily.getBytes(),
                     (deterTimes.get(4) + "\0").getBytes());
Range range = new Range(startKey, true, endKey, false);

Еще одна ловушка, с которой вам следует быть осторожным, это использовать String.getBytes() для получения ваших байтовых массивов без указания кодировки.Было бы лучше использовать что-то непротиворечивое, например "abc".getBytes(StandardCharsets.UTF_8) (хотя я обычно делаю статический импорт, поэтому я могу указать только UTF_8).

0 голосов
/ 13 ноября 2018

Здесь работает диапазон включительно, но, возможно, есть проблема со значениями, которые вы добавляете к нему

Это было бы проще диагностировать с помощью выходных данных, но есть вероятность, что вы ожидаете, что время сдерживания будет вышепотому что массив начинается с нуля, поэтому вы видите на определенное время меньше ожидаемого?

Если это не так, пожалуйста, поделитесь своим выводом

...