API пакетного чтения Aerospike принимает на вход массив наборов следующим образом:
final Key[] keys1 = new Key[3];
keys1[0] = new Key(config.getNamespace(), config.getSetName(1)), key);
keys1[1] = new Key(config.getNamespace(), config.getSetName(2)), key);
keys1[2] = new Key(config.getNamespace(), config.getSetName(3)), key);
И возвращает ответ в виде массива записей (Record[3]) с элементами из одного и того же набора в списке записей в правильном порядке, если все три набора содержат ключ.
Если в одном из наборов ключ отсутствует, я получаю ответ как Record[2] и не могу связать элементы с исходным набором.
Есть ли способ обойти это? Мои наборы сгруппированы по часам и по дням. Я хочу сделать только один вызов aerospike и иметь возможность различать данные между наборами.
Я не хочу создавать составные ключи (огромное количество ключей: 10 ^ 9), а также не могу создавать несколько пространств имен из-за того, что запрос предположительно становится дорогим.
Я заметил, что вы просили меня прокомментировать. Я смоделировал вашу проблему в Jupyter Notebook. Позвольте мне опубликовать соответствующие сегменты кода. Как сказал @kporter, для записей, которые отсутствуют, он возвращает ноль.
Key key1 = new Key("test", "testSet1", 1);
Key key2 = new Key("test", "testSet2", 2); // We will not create this record
Key key3 = new Key("test", "testSet3", 3);
Key key4 = new Key("test", "testSet4", 4);
Bin b1 = new Bin("bin1", 100);
Bin b2 = new Bin("bin1", 200);
Bin b3 = new Bin("bin1", 300);
Bin b4 = new Bin("bin1", 400);
client.put(null, key1, b1);
//client.put(null, key2, b2); //Skipping so its a null record
client.put(null, key3, b3);
client.put(null, key4, b4);
Это создает 3 записи в ключах key1, key3 и key4. Теперь давайте выполним пакетное чтение:
BatchPolicy batchPolicy = new BatchPolicy();
Record [] bReads = client.get(batchPolicy, new Key[] {key1, key2, key3, key4});
// process the batch reads
for (int i = 0; i < bReads.length; i++) {
Record bRead = bReads[i];
if (bRead != null) { // check individual record
long bin1Val = bRead.getLong("bin1");
System.out.format("Result[%d]: bin1: %d\n",i, bin1Val);
}
else { // error in individual key's operations
System.out.format("Result[%d]: not found: \n", i);
}
}
Выход:
Result[0]: bin1: 100
Result[1]: not found:
Result[2]: bin1: 300
Result[3]: bin1: 400
Пробовал несколько раз, это первое, что я попробовал. Уверен, что нет, по крайней мере, в версии 6.0. Какую версию вы используете?
Я использую последнюю версию E-7.0.0.8 и Java Client 7.2.1, но должен работать так же с версией сервера 6.0. Не уверен, что до версии 6.0 — BatchPolicy.respondAllKeys должно иметь значение true (по умолчанию), что в любом случае игнорирует ошибку «ключ не найден» и поэтому должно работать даже с false для поиска нулевых записей.
У меня была другая установка с сервером E-6.2.0.7 и клиентом Java 6.0.0 - там тоже работало, как и выше.
Поверьте, вы не выходите за пределы максимального количества имен в 1023 для вашей версии сервера. (На сервере 7.0 оно увеличилось до максимума 4095 наборов.)
Обнаружено, что мы использовали специальную оболочку ответа, которая удаляла в ответ нулевые значения.
Тайна раскрыта! Спасибо, что вернулись обратно.
Не могли бы вы поделиться кодом, который показывает пакетный вызов? Ожидается, что вы получите ответ
records[3]
на вводkeys[3]
. Неудачные попытки будут отображаться какnull
в массиве ответов.