OrientDB — как сделать графовый LEFT JOIN

Автор: Aport Вторник, Январь 27th, 2015 Нет комментариев

Рубрика: Разное

Давайте попробуем разобраться, как работать с джоинами классов.

Статья базируется на предыдущей статье, поэтому сначала изучите ее и создайте все вершины и ребра, которые мы создали там.

И для начала, кому интересно:

Прежде чем начать, хочу чтобы Вы знали, LEFT JOIN в OrientDB нет, потому что он в графовой базе не нужен, и это вначале изучения сложно понять, но я попробую объяснить. Дело в том, что даже разные виды объектов в OrientDB нужно связывать (если Вы хотите аля LEFT JOIN). В нашем случае это Города и Телефоны (условимся что есть телефоны по которым можно дозвониться в города). В реляционной базе данных мы бы связали город Rome с телефонами, используя отдельную таблицу связей (получилась бы связь один ко многим). В OrientDB в качестве связующей таблицы выступает класс E, в нем хранятся все возможные связи всех возможных объектов, т.е. там связь многие ко многим.

Ну что ж, приступим. В этой статье нам понадобятся следующие данные:

create class Info extends V

create vertex Info set phone = «123456789″

Итак, телефон мы добавили, теперь добавим прямую связь города и телефона:

create edge from #12:0 to #13:0

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

orientdb {cities}> select from V

----+-----+--------+--------+------+---------
#   |@RID |out_    |in_     |city  |phone
----+-----+--------+--------+------+---------
0   |#12:0|[size=5]|[size=2]|Rome  |null
1   |#12:1|[size=2]|[size=2]|London|null
2   |#12:2|[size=2]|[size=2]|Berlin|null
3   |#12:3|[size=2]|[size=3]|Madrid|null
4   |#12:4|[size=2]|[size=2]|Paris |null
5   |#13:0|null    |#12:0   |null  |123456789
----+-----+--------+--------+------+---------

orientdb {cities}> select from Info

----+-----+---------+------
#   |@RID |phone    |in_
----+-----+---------+------
0   |#13:0|123456789|#12:0
----+-----+---------+------

А теперь, добавим еще один телефон:

create vertex Info set phone = «567891234″

+ добавим связь и пометим эту связь меткой cityPhone с значением 2 (это значение я присвоил просто так, что-то вроде второй телефон).

create edge from #12:0 to #13:1 set cityPhone = 2

в итоге мы имеем связь, которая попала во все три класса:

orientdb {cities}> select from E

----+------+--------+-----+-----+---------
#   |@RID  |distance|out  |in   |cityPhone

----+------+--------+-----+-----+---------
0   |#10:0 |1234    |#12:0|#12:3|null
1   |#10:1 |1106    |#12:0|#12:4|null
2   |#10:2 |1106    |#12:4|#12:0|null
3   |#10:3 |1054    |#12:4|#12:3|null
4   |#10:4 |1054    |#12:3|#12:4|null
5   |#10:5 |1267    |#12:3|#12:1|null
6   |#10:6 |1267    |#12:1|#12:3|null
7   |#10:7 |930     |#12:1|#12:2|null
8   |#10:8 |930     |#12:2|#12:1|null
9   |#10:9 |1183    |#12:2|#12:0|null
10  |#10:10|1183    |#12:0|#12:2|null
11  |#10:11|null    |#12:0|#13:1|2        

----+------+--------+-----+-----+---------

orientdb {cities}> select from Info

----+-----+---------+------
#   |@RID |phone    |in_   

----+-----+---------+------
0   |#13:0|123456789|#12:0
1   |#13:1|567891234|#10:11

----+-----+---------+------

orientdb {cities}> select from V

----+-----+--------+--------+------+---------
#   |@RID |out_    |in_     |city  |phone    

----+-----+--------+--------+------+---------
0   |#12:0|[size=5]|[size=2]|Rome  |null
1   |#12:1|[size=2]|[size=2]|London|null
2   |#12:2|[size=2]|[size=2]|Berlin|null
3   |#12:3|[size=2]|[size=3]|Madrid|null
4   |#12:4|[size=2]|[size=2]|Paris |null
5   |#13:0|null    |#12:0   |null  |123456789
6   |#13:1|null    |#10:11  |null  |567891234

----+-----+--------+--------+------+---------

Надеюсь текущая картина Вас не смутила, иначе прочитайте предыдущую статью, а затем еще раз эту с самого начала.

Итак, мы помним, что out() возвращает нам все связи с текущим объектом:

orientdb {cities}> select expand(out()) from #12:0

----+-----+--------+--------+------+---------
#   |@RID |in_     |out_    |city  |phone    

----+-----+--------+--------+------+---------
0   |#12:4|[size=2]|[size=2]|Paris |null
1   |#12:2|[size=2]|[size=2]|Berlin|null
2   |#12:3|[size=3]|[size=2]|Madrid|null
3   |#13:0|#12:0   |null    |null  |123456789
4   |#13:1|#10:11  |null    |null  |567891234

----+-----+--------+--------+------+---------

Таким образом мы получаем все объекты связанные с объектом #12:0 и чтобы показать эти данные на клиентской части, нужно просто их правильно скомпоновать (исключая значения null в полях).

заметка: если хочется, можно вытащить только телефоны:

select expand(out()['phone']) from #12:0

Тем не менее, Вас наверное интересует вопрос, а как мне быть, если нужно получить такие данные сразу по нескольким объектам, например #12:0 и #12:1, и первое что приходит в голову:

select expand(out()) from My where @RID = #12:0 or @RID = #12:1

и если Вы не в курсе, этот запрос можно написать проще:

orientdb {cities}> select expand( out() ) from [#12:0, #12:1]

----+-----+--------+--------+------+---------
#   |@RID |in_     |out_    |city  |phone    

----+-----+--------+--------+------+---------
0   |#12:4|[size=2]|[size=2]|Paris |null
1   |#12:2|[size=2]|[size=2]|Berlin|null
2   |#12:3|[size=3]|[size=2]|Madrid|null
3   |#13:0|#12:0   |null    |null  |123456789
4   |#13:1|#10:11  |null    |null  |567891234
5   |#12:3|[size=3]|[size=2]|Madrid|null
6   |#12:2|[size=2]|[size=2]|Berlin|null     

----+-----+--------+--------+------+---------

Отлично, данные получены, но тут у Вас сразу возникает вопрос — а как мне узнать, какие данные относятся к объекту #12:0 а какие #12:1? В консоле это можно сделать с помощью функции toJSON(), но для начала давайте посмотрим кол-во связей по данным объектам:

select @RID, out() from [#12:0, #12:1]

----+-----+-----+----
#   |@RID |RID  |out
----+-----+-----+----
0   |#-2:1|#12:0|[5]
1   |#-2:2|#12:1|[2]
----+-----+-----+----

обратите внимание, при реальной выборке данных, чтобы получить вместо ссылочных указателей ( ID связей ) нам достаточно указать нужный нам fetchPlan, лично я указал значение *:3 и получил коллекцию объектов с глубиной 3.

1. Привожу пример последнего (выше описанного) запроса в виде RESTful:

http://localhost:2480/query/cities/sql/select%20%40RID%2C%20out%28%29%20from%20%5B%2312%3A0%2C%20%2312%3A1%5D/12/*:3

2. Привожу пример последнего (выше описанного) запроса в консоли:

select @RID, out().toJSON(‘fetchPlan:*:3‘) from [#12:0, #12:1]

В результате вернется JSON строка с колекцией в которую подгружены документы:

Array
(
    [0] => stdClass Object
        (
            [@type] => d
            [@rid] => #-2:1
            [@version] => 0
            [RID] => stdClass Object
                (
                    [@type] => d
                    [@rid] => #12:0
                    [@version] => 7
                    [@class] => My
                    [out_] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:1
                                    [@version] => 1
                                    [@class] => E
                                    [in] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #12:4
                                            [@version] => 4
                                            [@class] => My
                                            [in_] => Array
                                                (
                                                    [0] => #10:1
                                                    [1] => #10:4
                                                )

                                            [out_] => Array
                                                (
                                                    [0] => #10:2
                                                    [1] => #10:3
                                                )

                                            [city] => Paris
                                            [@fieldTypes] => in_=g,out_=g
                                        )

                                    [distance] => 1106
                                    [out] => #12:0
                                )

                            [1] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:10
                                    [@version] => 1
                                    [@class] => E
                                    [in] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #12:2
                                            [@version] => 4
                                            [@class] => My
                                            [in_] => Array
                                                (
                                                    [0] => #10:7
                                                    [1] => #10:10
                                                )

                                            [out_] => Array
                                                (
                                                    [0] => #10:8
                                                    [1] => #10:9
                                                )

                                            [city] => Berlin
                                            [@fieldTypes] => in_=g,out_=g
                                        )

                                    [distance] => 1183
                                    [out] => #12:0
                                )

                            [2] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:0
                                    [@version] => 4
                                    [@class] => E
                                    [in] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #12:3
                                            [@version] => 5
                                            [@class] => My
                                            [in_] => Array
                                                (
                                                    [0] => #10:3
                                                    [1] => #10:6
                                                    [2] => #10:0
                                                )

                                            [out_] => Array
                                                (
                                                    [0] => #10:4
                                                    [1] => #10:5
                                                )

                                            [city] => Madrid
                                            [@fieldTypes] => in_=g,out_=g
                                        )

                                    [distance] => 1234
                                    [out] => #12:0
                                )

                            [3] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #13:0
                                    [@version] => 1
                                    [@class] => Info
                                    [phone] => 123456789
                                    [in_] => #12:0
                                )

                            [4] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:11
                                    [@version] => 1
                                    [@class] => E
                                    [in] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #13:1
                                            [@version] => 1
                                            [@class] => Info
                                            [phone] => 567891234
                                            [in_] => #10:11
                                        )

                                    [cityPhone] => 2
                                    [out] => #12:0
                                )

                        )

                    [in_] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:2
                                    [@version] => 1
                                    [@class] => E
                                    [distance] => 1106
                                    [out] => #12:4
                                    [in] => #12:0
                                )

                            [1] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:9
                                    [@version] => 1
                                    [@class] => E
                                    [distance] => 1183
                                    [out] => #12:2
                                    [in] => #12:0
                                )

                        )

                    [city] => Rome
                    [@fieldTypes] => out_=g,in_=g
                )

            [out] => Array
                (
                    [0] => #12:4
                    [1] => #12:2
                    [2] => #12:3
                    [3] => #13:0
                    [4] => #13:1
                )

        )

    [1] => stdClass Object
        (
            [@type] => d
            [@rid] => #-2:2
            [@version] => 0
            [RID] => stdClass Object
                (
                    [@type] => d
                    [@rid] => #12:1
                    [@version] => 4
                    [@class] => My
                    [in_] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:5
                                    [@version] => 1
                                    [@class] => E
                                    [distance] => 1267
                                    [out] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #12:3
                                            [@version] => 5
                                            [@class] => My
                                            [in_] => Array
                                                (
                                                    [0] => #10:3
                                                    [1] => #10:6
                                                    [2] => #10:0
                                                )

                                            [out_] => Array
                                                (
                                                    [0] => #10:4
                                                    [1] => #10:5
                                                )

                                            [city] => Madrid
                                            [@fieldTypes] => in_=g,out_=g
                                        )

                                    [in] => #12:1
                                )

                            [1] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:8
                                    [@version] => 1
                                    [@class] => E
                                    [distance] => 930
                                    [out] => stdClass Object
                                        (
                                            [@type] => d
                                            [@rid] => #12:2
                                            [@version] => 4
                                            [@class] => My
                                            [in_] => Array
                                                (
                                                    [0] => #10:7
                                                    [1] => #10:10
                                                )

                                            [out_] => Array
                                                (
                                                    [0] => #10:8
                                                    [1] => #10:9
                                                )

                                            [city] => Berlin
                                            [@fieldTypes] => in_=g,out_=g
                                        )

                                    [in] => #12:1
                                )

                        )

                    [out_] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:6
                                    [@version] => 1
                                    [@class] => E
                                    [in] => #12:3
                                    [distance] => 1267
                                    [out] => #12:1
                                )

                            [1] => stdClass Object
                                (
                                    [@type] => d
                                    [@rid] => #10:7
                                    [@version] => 1
                                    [@class] => E
                                    [in] => #12:2
                                    [distance] => 930
                                    [out] => #12:1
                                )

                        )

                    [city] => London
                    [@fieldTypes] => in_=g,out_=g
                )

            [out] => Array
                (
                    [0] => #12:3
                    [1] => #12:2
                )

        )

)

Удачного освоения господа, а если есть вопросы, прошу в комментарии или в группу OrientDB.

 

Источник: yapro.ru

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

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты