Доброго времени суток!
В прошлом посте я рассказал о том как извлекать одну запись из NoSQL базы. В случае одной записи все проще простого. А как быть если я хочу вытащить несколько записей? Как сказал бы анатолий Кашперовский, если хочешь вытащить несколько записаей - просто возьми их:)
Итак, перед тем как я буду описывать конкретные реализации инструментов извлечения, хотелось бы рассказать о концепции мультиселекта. Вытаскивать можно ключи с различной вложеностью (можно вытаскивать ключ и его детей, внуков итп...) слева на право, но не наоборот (правила как в прямом префиксном индексе).
Например дано:
major1/major2/-/minor1/
major1/major3/-/minor1/
major1/major4/-/minor1/
major2/major2/-/minor1/
Можно извлечь по запросу aka like 'major1%':
major1/major2/-/minor1/
major1/major3/-/minor1/
major1/major4/-/minor1/
Но нельзя извлечь по запросу aka like '%major2%'.
major1/major2/-/minor1/
major2/major2/-/minor1/
Надеюсь, что не очень запутал, а если запутал,то надеюсь что дальше будет понятнее.
В Oracle NoSQL DB на данный момент существует 3 способа извлечения множество строк.
multiGet() - самый прямолинейный способ извлечени данных фетчит все и сразу в память. Испоьзует структуру SortedMap, данные умеет возвразать в отсортированном порядке. Требует полного major ключа. Приведу пример.
Дано:
major1/major2/-/minor1/
major1/major2/-/minor2/
major1/major3/-/minor1/
Можно извлечь значения ключей (like 'major1/major2%'):
major1/major2/-/minor1/
major1/major2/-/minor2/
Но нельзя (like 'major1/%'):
major1/major2/-/minor1/
major1/major2/-/minor2/
major1/major3/-/minor1/
multiGetIterator() - умеет возвращать данные пачками (если достаем оч. много данных, будет не камельфо, если за одну итерацию в память у нас уйдет терабайт данных). Данные умеет возвращать в отсортированном порядке. Так же как и multiGet() требует полного major key.
storeIterator() - умеет доставать записи пачками. НЕ требуется полного major ключа достаточно куска major key. Сортировать не умеет. Мой неготивный опыт работы с этим оператором - он не возвращает строк по полному major пути. Почему не заню, скорее всего не до разобрался. Впрочем workaround прост - используем для этого multiGet().
Для упрощения своей работы я создал 2 метода: SelectWhere и SelectWhereFullMajor(опять же таки привет моему полу-реляционному мышлению).
public static void SelectWhere(String sKey,KVStore myStore) {
Key myKey = ParseKey.ParseKey(sKey);
try {
Iterator<KeyValueVersion> myrecords =
myStore.storeIterator(Direction.UNORDERED, 0, myKey, null, Depth.PARENT_AND_DESCENDANTS);
while (myrecords.hasNext()) {
Key key = myrecords.next().getKey();
ValueVersion vv = myStore.get(key);
Value v = vv.getValue();
data = new String(v.getValue());
List<String> majorPath1 = key.getMajorPath();
List<String> minorPath1 = key.getMinorPath();
System.out.println(majorPath1 + " - " + minorPath1 + ":" + data);
}
} catch (RequestTimeoutException re) {
System.out.println(re.getTimeoutMs());
} catch (FaultException fe) {
} finally {
}
}
public static void SelectWhereFullMajor(String sKey,KVStore myStore) {
Key myKey = ParseKey.ParseKey(sKey);
try {
// Initialize Matrix
SortedMap<Key, ValueVersion> myrecords = null;
myrecords = myStore.multiGet(myKey, null, Depth.PARENT_AND_DESCENDANTS, Consistency.ABSOLUTE, 1, TimeUnit.DAYS);
for (SortedMap.Entry<Key, ValueVersion> entry : myrecords.entrySet()) {
ValueVersion vv = entry.getValue();
Value v = vv.getValue();
Key myKeyOut = entry.getKey();
String data = new String(v.getValue());
List<String> majorPath1 = myKeyOut.getMajorPath();
List<String> minorPath1 = myKeyOut.getMinorPath();
System.out.println(majorPath1 + " - " + minorPath1 + ":" + data);
}
} catch (RequestTimeoutException re) {
System.out.println(re.getTimeoutMs());
} catch (FaultException fe) {
} finally {
}
}
при описании метода мы определяем глубину чтения (только указанные ключи, ключи и дети...)