Spec-Zone.ru › RethinkDB python

Команда 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

Описание

Data Modeling Illustration

Объединить таблицы с использованием поля или функции в левой последовательности, сопоставляя первичные ключи или вторичные индексы в правой таблице. 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" },
	...
]

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

  • inner_join
  • outer_join
  • without
  • zip

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

Spec-Zone.ru

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