Давайте попробуем разобраться, как работать с джоинами классов.
Статья базируется на предыдущей статье, поэтому сначала изучите ее и создайте все вершины и ребра, которые мы создали там.
И для начала, кому интересно:
Прежде чем начать, хочу чтобы Вы знали, 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.
Комментарии
Комментариев пока нет.