суббота, 9 июня 2012 г.

Статья 7. CRUD. Retrieve part2.

Доброго времени суток!
В прошлом посте я рассказал о том как извлекать одну запись из 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 {
        }
    }


при описании метода мы определяем глубину чтения (только указанные ключи, ключи и дети...) 

Если у вас есть какие-либо вопросы по Oracle NoSQL - задавайте в комментах, постараюсь ответить, либо пишите на oracle.nosql@gmail.com.

Комментариев нет:

Отправить комментарий