Много-много обновлений в MongoDB без транзакций - PullRequest
9 голосов
/ 14 февраля 2011

У меня есть две коллекции с отношением многие ко многим.Я хочу сохранить массив связанных ObjectIds в обоих документах, чтобы я мог быстро взять Документ A и извлечь все связанные Документы B. И наоборот.

Создание этой ссылки - двухэтапный процесс

  1. Добавление ObjectId документа A в документ B
  2. Добавление ObjectId документа B в документ A

После просмотра видео MongoDB я обнаружил, что это рекомендуемый способ хранения многихотношения между двумя коллекциями

Я должен быть уверен, что оба обновления сделаны.Каков рекомендуемый способ надежного решения этого важного двухэтапного процесса без транзакции?

Я мог бы сжать эти отношения в одну коллекцию ссылок, преимущество в том, что в одном обновлении нет шансов, что Документ B пропустит ссылку на Документ A. Недостатком является то, что я на самом деле не использую MongoDB по назначению.Но поскольку существует только одно обновление, кажется более надежным иметь коллекцию ссылок, которая определяет отношение «многие ко многим».

Стоит ли использовать безопасный режим и вручную проверять, что данные были введены впоследствии, и попробоватьопять на провал?Или я должен представлять отношение «многие ко многим» только в одной из коллекций и полагаться на индекс, чтобы убедиться, что я все еще могу быстро получить связанные документы?

Есть какие-нибудь рекомендации?Спасибо

Ответы [ 3 ]

5 голосов
/ 15 февраля 2011

@ Гарет , у вас есть несколько законных способов сделать это.Поэтому их ключевой проблемой является то, как вы планируете запрашивать данные (т.е.: какие запросы должны быть быстрыми )

Вот несколько методов.

Метод № 1: коллекция «ссылок»

Вы можете создать коллекцию, которая просто содержит сопоставления между коллекциями.

Плюсы:

  • Поддерживает атомарные обновления, чтобы данные не терялись

Минусы:

  • Дополнительный запрос при попытке перемещения между коллекциями

Метод № 2: хранить копии небольших сопоставлений в большой коллекции

Например: у вас есть миллионы Products, но только сотня Categories,Тогда вы должны хранить Categories как массив внутри каждого Product.

Плюсы:

  • Наименьшая площадь
  • Требуется толькоодно обновление

Минусы:

  • Дополнительный запрос, если вы идете "неправильным путем"

Метод № 3: хранить копии всех отображений в обеих коллекциях

(что вы предлагаете)

Плюсы:

  • Доступ к одному запросу для перемещения между коллекциями

Минусы:

  • Потенциально большие индексы
  • Требуются транзакции (?)

Давайте поговорим о «транзакциях потребностей».Существует несколько способов выполнения транзакций, и это действительно зависит от того, какой тип безопасности вам необходим.

Следует ли мне использовать безопасный режим и вручную проверять данные, поступившие впоследствии, и повторять попытку в случае сбоя?

Вы определенно можете это сделать.Вы должны спросить себя, что хуже всего случится, если произойдет сбой только одного из сохранений?

Метод # 4: поставить в очередь изменения

Не знаюЗнайте, работали ли вы когда-либо с очередями, но если у вас есть некоторая свобода действий, вы можете создать простую очередь и иметь разные задания, которые обновляют их соответствующие коллекции.

Это гораздо более продвинутое решение.Я бы предпочел пойти с № 2 или № 3.

2 голосов
/ 14 февраля 2011

Почему бы вам не создать выделенную коллекцию, содержащую отношения между А и В в виде выделенных строк / документов, как это можно было бы сделать в СУБД. Вы можете изменить таблицу отношений с помощью одной операции, которая, конечно, атомарна.

0 голосов
/ 06 октября 2012

Должен ли я использовать безопасный режим и вручную проверять данные, поступившие впоследствии, и пытаться снова при сбое?

Да, это подход, но есть и другой - вы можете реализовать оптимистическую транзакцию. Это имеет некоторые накладные расходы и ограничения, но гарантирует согласованность данных. Я написал пример и некоторые пояснения на странице GitHub .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...