Команда ReQL: eq_join
Синтаксис команды
sequence.eq_join(left_field, right_table[, index='id', ordered=False]) → sequence sequence.eq_join(function, right_table[, index='id', ordered=False]) → sequence
Описание
Объединить таблицы с использованием поля или функции в левой последовательности, сопоставляя первичные ключи или вторичные индексы в правой таблице. eq_join более эффективен, чем другие типы объединения ReQL, и работает намного быстрее. Документы в наборе результатов состоят из пар документов левой и правой таблиц, сопоставленных, когда поле в левой части существует и не является пустым, и в указанном индексе правой части существует запись с этим значением поля.
Набор результатов eq_join — это поток или массив объектов. Каждый объект в возвращаемом наборе будет объектом вида { left: <left-document>, right: <right-document> }, где значения left и right будут объединёнными документами. Используйте команду zip для объединения полей left и right.
Результаты eq_join по умолчанию не упорядочены. Опциональный параметр ordered=True заставит eq_join упорядочить вывод на основе входного потока левой части. (Если для документа из левой части существует несколько совпадений в правой части, их порядок не гарантируется, даже если ordered — True.) Требование упорядоченных результатов может значительно замедлить eq_join, и во многих случаях это упорядочивание не требуется. (См. первый пример, в котором упорядоченные результаты получаются с помощью order_by после eq_join.)
Предположим, таблица players содержит эти документы:
[
{ 'id': 1, 'player': 'George', 'game_id': 1 },
{ 'id': 2, 'player': 'Agatha', 'game_id': 3 },
{ 'id': 3, 'player': 'Fred', 'game_id': 2 },
{ 'id': 4, 'player': 'Marie', 'game_id': 2 },
{ 'id': 5, 'player': 'Earnest', 'game_id': 1 },
{ 'id': 6, 'player': 'Beth', 'game_id': 3 }
]
Таблица games содержит эти документы:
[
{ 'id': 1, 'field': 'Little Delving' },
{ 'id': 2, 'field': 'Rushock Bog' },
{ 'id': 3, 'field': 'Bucklebury' }
]
Пример: Сопоставить игроков с играми, в которых они играли друг против друга.
Объедините эти таблицы с помощью game_id для таблицы players и id для таблицы games:
r.table('players').eq_join('game_id', r.table('games')).run(conn)
Это вернёт набор результатов, похожий на следующий:
[
{
"left" : { "game_id" : 3, "id" : 2, "player" : "Agatha" },
"right" : { "id" : 3, "field" : "Bucklebury" }
},
{
"left" : { "game_id" : 2, "id" : 3, "player" : "Fred" },
"right" : { "id" : 2, "field" : "Rushock Bog" }
},
...
]
Скорее всего, вам нужен результат использования zip с этим. Для большей ясности, мы будем использовать without для удаления поля id из таблицы games (оно конфликтует с полем id для таблицы players и, в любом случае, избыточно), и мы будем упорядочивать его по играм.
r.table('players').eq_join('game_id', r.table('games')).without({'right': "id"}).zip().order_by('game_id').run(conn)
[
{ "field": "Little Delving", "game_id": 1, "id": 5, "player": "Earnest" },
{ "field": "Little Delving", "game_id": 1, "id": 1, "player": "George" },
{ "field": "Rushock Bog", "game_id": 2, "id": 3, "player": "Fred" },
{ "field": "Rushock Bog", "game_id": 2, "id": 4, "player": "Marie" },
{ "field": "Bucklebury", "game_id": 3, "id": 6, "player": "Beth" },
{ "field": "Bucklebury", "game_id": 3, "id": 2, "player": "Agatha" }
]
Для получения дополнительной информации см. Объединение таблиц в RethinkDB.
Пример: Использование вторичного индекса в правой таблице вместо первичного ключа. Если у игроков есть вторичный индекс по их городам, мы можем получить список арен с игроками в одном районе.
r.table('players').eq_join('city_id', r.table('arenas'), index='city_id').run(conn)
Пример: Использование вложенного ключа в качестве поля объединения. Предположим, документы в таблице players были структурированы так:
{ 'id': 1, 'player': 'George', 'game': {'id': 1} },
{ 'id': 2, 'player': 'Agatha', 'game': {'id': 3} },
...
Просто укажите поле с помощью команды row вместо строки.
r.table('players').eq_join(r.row['game']['id'], r.table('games')).without({'right': 'id'}).zip().run(conn)
[
{ "field": "Little Delving", "game": { "id": 1 }, "id": 5, "player": "Earnest" },
{ "field": "Little Delving", "game": { "id": 1 }, "id": 1, "player": "George" },
...
]
Пример: Использование функции вместо поля для объединения на основе более сложного выражения. Предположим, игроки имеют списки любимых игр, отсортированных по порядку, в поле, например, "favorites": [3, 2, 1]. Получить список игроков и их любимую игру:
r.table('players').eq_join(
lambda player: player['favorites'].nth(0),
r.table('games')
).without([{'left': ['favorites', 'game_id', 'id']}, {'right': 'id'}]).zip()
Результат:
[
{ "field": "Rushock Bog", "name": "Fred" },
{ "field": "Little Delving", "name": "George" },
...
]
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/python/eq_join/