Команда ReQL: eqJoin
Синтаксис команды
sequence.eqJoin(leftField, rightTable[, {index: 'id', ordered: false}]) → sequence
sequence.eqJoin(function, rightTable[, {index: 'id', ordered: false}]) → sequence
Описание
Объединяет таблицы, используя поле или функцию в левой последовательности, сопоставляя первичные ключи или вторичные индексы в правой таблице. eqJoin более эффективен, чем другие типы объединений ReQL, и работает намного быстрее. Документы в наборе результатов состоят из пар документов левой и правой таблиц, сопоставленных, когда поле в левой стороне существует и не является нулевым, и существует запись с значением этого поля в указанном индексе правой стороны.
Результат выполнения eqJoin — это поток или массив объектов. Каждый объект в возвращаемом наборе будет объектом вида { left: <left-document>, right: <right-document> }, где значения left и right будут объединёнными документами. Используйте команду zip для объединения полей left и right.
Результаты eqJoin по умолчанию не упорядочены. Параметр ordered: true позволит eqJoin упорядочить вывод на основе входного потока слева. (Если для документа из левой стороны существует несколько совпадений в правой стороне, их порядок не гарантирован, даже если ordered равен true.) Требование упорядоченных результатов может значительно замедлить eqJoin, и во многих случаях этого упорядочения не потребуется. (См. первый пример, в котором упорядоченные результаты получаются путём использования orderBy после eqJoin.)
Предположим, таблица players содержит следующие документы:
[
{ id: 1, player: 'George', gameId: 1 },
{ id: 2, player: 'Agatha', gameId: 3 },
{ id: 3, player: 'Fred', gameId: 2 },
{ id: 4, player: 'Marie', gameId: 2 },
{ id: 5, player: 'Earnest', gameId: 1 },
{ id: 6, player: 'Beth', gameId: 3 }
]
Таблица games содержит следующие документы:
[
{ id: 1, field: 'Little Delving' },
{ id: 2, field: 'Rushock Bog' },
{ id: 3, field: 'Bucklebury' }
]
Пример: Сопоставление игроков с играми, в которых они участвовали.
Объедините эти таблицы, используя gameId для таблицы players и id для таблицы games:
r.table('players').eqJoin('gameId', r.table('games')).run(conn, callback)
Это вернёт набор результатов, подобный следующему:
[
{
"left" : { "gameId" : 3, "id" : 2, "player" : "Agatha" },
"right" : { "id" : 3, "field" : "Bucklebury" }
},
{
"left" : { "gameId" : 2, "id" : 3, "player" : "Fred" },
"right" : { "id" : 2, "field" : "Rushock Bog" }
},
...
]
Вероятно, вам нужно будет использовать zip с этим результатом. Для ясности, мы используем without для удаления поля id из таблицы games (оно конфликтует с полем id в таблице players и, в любом случае, избыточно), и мы упорядочим его по полю games.
r.table('players').eqJoin('gameId', r.table('games')).without({right: "id"}).zip().orderBy('gameId').run(conn, callback)
[
{ "field": "Little Delving", "gameId": 1, "id": 5, "player": "Earnest" },
{ "field": "Little Delving", "gameId": 1, "id": 1, "player": "George" },
{ "field": "Rushock Bog", "gameId": 2, "id": 3, "player": "Fred" },
{ "field": "Rushock Bog", "gameId": 2, "id": 4, "player": "Marie" },
{ "field": "Bucklebury", "gameId": 3, "id": 6, "player": "Beth" },
{ "field": "Bucklebury", "gameId": 3, "id": 2, "player": "Agatha" }
]
Для получения дополнительной информации см. Объединения таблиц в RethinkDB.
Пример: Использование вторичного индекса в правой таблице вместо первичного ключа. Если у игроков есть вторичный индекс по городам, мы можем получить список арен с игроками в одном районе.
r.table('players').eqJoin('cityId', r.table('arenas'), {index: 'cityId'}).run(conn, callback)
Пример: Использование вложенного ключа как поля объединения. Предположим, документы в таблице players имеют следующую структуру:
{ id: 1, player: 'George', game: {id: 1} },
{ id: 2, player: 'Agatha', game: {id: 3} },
...
Просто укажите поле, используя команду row вместо строки.
r.table('players').eqJoin(r.row('game')('id'), r.table('games')).without({right: 'id'}).zip()
[
{ "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').eqJoin(function (player) {
return player('favorites').nth(0)
}, r.table('games')).without([{left: ['favorites', 'gameId', '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/javascript/eq_join/