Подтвердить что ты не робот

Является ли перемещение документов между коллекциями хорошим способом представления изменений состояния в MongoDB?

У меня есть две коллекции: одна (A), содержащая элементы для обработки (относительно небольшие) и один ( B) с уже обработанными (довольно большими, с дополнительными поля результатов).

Элементы читаются с A, обрабатываются и сохраняются() 'd до B, а затем удаляются()' d из A.

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

Я столкнулся с двумя проблемами:

  • если вы удаляете() или сохраняете() тайм-аут или иным образом терпите неудачу при загрузке, я полностью теряю элемент или обрабатываю его дважды
  • если оба не работают, побочные эффекты происходят, но нет записи о том, что

Я могу обойти случай с двойным сбоем с помощью блокировок findAndModify (в противном случае не требуется блокировка на уровне процесса), но тогда у нас есть проблемы с устаревшим блокированием, и частичные сбои все еще могут произойти. Невозможно ли физически удалить + сохранить в разные коллекции, насколько я могу судить (может быть, по дизайну?)

Есть ли лучшая практика для этой ситуации?

4b9b3361

Ответ 1

Невозможно физически удалить + сохранить в разные коллекции, насколько я могу судить (возможно, по дизайну?)

Да, это по дизайну. MongoDB явно не предоставляет объединения или транзакции. Удалить + Сохранить - это форма транзакции.

Есть ли лучшая практика для этой ситуации?

У вас действительно есть два варианта с низкой степенью сложности, оба включают findAndModify.

Вариант №1: отдельная коллекция

Основываясь на вашем описании, вы в основном создаете очередь с некоторыми дополнительными функциями. Если вы используете одну коллекцию, вы используете findAndModify для обновления состояния каждого элемента по мере его обработки.

К сожалению, это означает, что вы потеряете это:... что "входящая" коллекция может храниться очень малой и быстрой.

Вариант № 2: две коллекции

Другим вариантом является в основном двухфазное принятие, используя findAndModify.

Взгляните на документы для этого здесь.

Как только элемент обрабатывается в A, вы устанавливаете для него поле для его удаления. Затем вы копируете этот элемент на B. После копирования в B вы можете удалить элемент из A.

Ответ 2

Я еще не пробовал это сам, но новая книга 50 советов и советов для разработчиков MongoDB несколько раз упоминает о использовании заданий cron (или служб/планировщиков) для очистки данных, подобных этому. Вы можете оставить документы в коллекции A помечены для удаления и запустить ежедневную работу, чтобы очистить их, уменьшив общую область исходной транзакции.

Из того, что я узнал до сих пор, я никогда не покидал базу данных в состоянии, когда я полагаюсь на следующее действие базы данных, если оно не является последним действием (журналирование будет повторно отправить последнее действие db при восстановлении). Например, у меня есть процесс регистрации трехэтапной учетной записи, когда я создаю пользователя в CollectionA, а затем добавляю другой связанный документ в CollectionB. Когда я создаю пользователя, я вставляю детали документа CollectionB в CollectionA в случае неудачной записи второй записи. Позже я напишу процесс, который удаляет встроенные данные из CollectionA, если документ в CollectionB существует

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