Spec-Zone.ru › RethinkDB java

Команда ReQL: eqJoin

Синтаксис команды

sequence.eqJoin(leftField, rightTable) → sequence
sequence.eqJoin(function, rightTable) → sequence

Описание

Data Modeling Illustration

Объединяет таблицы, используя поле или функцию в левой последовательности, соответствующую первичным ключам или вторичным индексам в правой таблице. eqJoin более эффективен, чем другие типы объединения ReQL, и работает значительно быстрее. Документы в наборе результатов состоят из пар документов левой и правой таблиц, соответствующих друг другу, когда поле в левой части существует, не является пустым и в указанном индексе правой части есть запись с соответствующим значением поля.

Результат выполнения eqJoin представляет собой поток или массив объектов. Каждый объект в возвращаемом наборе будет объектом вида { "left": <left-document>, "right": <right-document> }, где значения left и right будут объединёнными документами. Используйте команду zip для объединения left и right полей.

Результаты eqJoin по умолчанию не упорядочены. Указание optArg('ordered', 'true') заставит eqJoin упорядочить вывод на основе входного потока левой части. (Если для документа в левой части есть несколько совпадений в правой части, их порядок не гарантируется, даже если ordered является true.) Требование упорядоченных результатов может значительно замедлить eqJoin, и во многих случаях эта сортировка не потребуется. (См. первый пример, в котором упорядоченные результаты получаются с помощью orderBy после eqJoin.)

Предположим, что таблица players содержит следующие документы (показаны в формате JSON):

[
    { "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 в таблице player и id в таблице games:

r.table("players").eqJoin("gameId", r.table("games")).run(conn);

Это вернёт набор результатов, похожий на следующий:

[
    {
        "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("game_id", r.table("games"))
 .without(r.hashMap("right", "id"))
 .zip()
 .orderBy("game_id")
 .run(conn);
[
    { "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("city_id", r.table("arenas"))
 .optArg("index", "city_id").run(conn);

Пример: Используйте вложенный ключ в качестве поля объединения. Предположим, что документы в таблице players имеют структуру:

{ "id": 1, "player": "George", "game": {"id": 1} },
{ "id": 2, "player": "Agatha", "game": {"id": 3} },
...

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

r.table("players").eqJoin(
    row -> row.g("game").g("id"),
    r.table("games")
).without(r.hashMap("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").eqJoin(
    player -> player.g("favorites").nth(0),
    r.table("games")
).without(
    r.array(r.hashMap("left", r.array("favorites", "game_id", "id")),
    r.hashMap("right", "id"))
).zip().run(conn);
[
	{ "field": "Rushock Bog", "name": "Fred" },
	{ "field": "Little Delving", "name": "George" },
	...
]

Связанные команды

  • innerJoin
  • outerJoin
  • without
  • zip

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/java/eq_join/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API