Давайте попробуем разобраться, как работать с джоинами классов.
Данную статью следует читать, если Вы разобрались с предыдущими статьями, поэтому сначала изучите их.
И для начала, кому интересно:
Суть задачи
Мы имеем 2 таблицы (2 класса вершин):
Необходимо узнать, по какому телефону можно дозвониться в город Rome.
Поехали
Первым делом создадим классы-вершин и добавим в них данные:
create class Cities extends V
create vertex Cities set city="Rome"
create vertex Cities set city="London"
create vertex Cities set city="Berlin"create class Phones extends V
create vertex Phones set phone = "123456789"
create vertex Phones set phone = "567891234"
Получили такой результат:
orientdb {cities}> select from Cities ----+-----+------ # |@RID |city ----+-----+------ 0 |#16:0|Rome 1 |#16:1|London 2 |#16:2|Berlin ----+-----+------ orientdb {cities}> select from Phones ----+-----+--------- # |@RID |phone ----+-----+--------- 0 |#17:0|123456789 1 |#17:1|567891234 ----+-----+---------
Отлично, теперь укажим, куда можно дозониться по имеющимся телефонам. Это можно сделать указывая ребра (EDGE).
Первым делом хочу сказать, что в предыдущих статьях, я намеренно упрощал работу с графами, тем самым делая немного неправильное их использование. Это было сделано, чтобы было проще понять, как работают графы, но не переживайте, теперь я покажу, как правильно.
В предыдущих примерах мы создавали ребра, даже не прибегая к созданию класса-ребер:
1. Раньше (неправильно) | 2. Теперь (правильно) |
и получали: orientdb {cities}> select from Cities ----+-----+------+----- # |@RID |city |out_ ----+-----+------+----- 0 |#16:0|Rome |#17:0 1 |#16:1|London|null 2 |#16:2|Berlin|null ----+-----+------+----- select from Cities where out_.phone = '123456789' ----+-----+-----+---- # |@RID |out_|city ----+-----+-----+---- 0 |#16:0|#17:0|Rome ----+-----+-----+---- |
и получили: orientdb {cities}> select from Cities ----+-----+------+---------------- # |@RID |city |out_CitiesPhones ----+-----+------+---------------- 0 |#16:0|Rome |#17:0 1 |#16:1|London|null 2 |#16:2|Berlin|null ----+-----+------+---------------- select from Cities where out_CitiesPhones.phone = '123456789' ----+-----+----------------+---- # |@RID |out_CitiesPhones|city ----+-----+----------------+---- 0 |#16:0|#17:0 |Rome ----+-----+----------------+---- |
Заметка: для воплощения правильного варианта, мы обязаны создать еще один класс-ребер под названием CitiesPhones:
create class CitiesPhones extends E
Казалось бы, в 1-ом варианте проще имя поля связи, зачем нам второй вариант? Ответ прост: 1-ый вариант перестанет работать, если у класса Cities появится out_-связь с еще одним классом-вершиной. Произойдет это потому, что OrientDB постарается держать все связи класса Cities со всеми другими классами-вершинами, в поле out_. И казалось бы, что здесь плохого? Но мы ведь понимаем, что может произойти такой случай, когда вы решите связать класс Cities например с классом граждан, которые проживают в указанных городах, назовем его Persons. И в классе Persons может быть такое же одноименное поле phone, как и в классе Phones. Таким образом выполнив запрос:
select from Cities where out_.phone = '123456789'
мы не получим результата, т.к. OrientDB не знает, указали Вы поле phone класса Phones или Вы указал поле phone класса Persons.
Именно в этом и заключается отличие использования правильного варианта. Удачного изучения, господа.