Можете ли вы поделиться своими мыслями о том, как бы вы реализовали управление версиями данных в MongoDB. (Я задал похожий вопрос относительно Кассандры . Если у вас есть какие-либо мысли, какой БД лучше для этого, поделитесь)
Предположим, мне нужно записать записи в простой адресной книге. (Записи адресной книги хранятся в виде плоских объектов JSON). Я ожидаю, что история
- будет использоваться нечасто
- будет использоваться сразу, чтобы представить его в стиле «машины времени»
- не будет больше версий, чем несколько сотен на одну запись. история не закончится.
Я рассматриваю следующие подходы:
Создайте новую коллекцию объектов для хранения истории записей или изменений в записях. Он будет хранить один объект на версию со ссылкой на запись адресной книги. Такие записи выглядят следующим образом:
{ '_id': 'новый идентификатор', 'user': user_id, «отметка времени»: отметка времени, 'address_book_id': 'идентификатор записи адресной книги' 'old_record': {'first_name': 'Jon', 'last_name': 'Doe' ...} }
Этот подход может быть изменен для хранения массива версий для каждого документа. Но это, кажется, медленный подход без каких-либо преимуществ.
Хранить версии как сериализованный (JSON) объект, прикрепленный к записям адресной книги. Я не уверен, как прикрепить такие объекты к документам MongoDB. Возможно, как массив строк. ( Смоделировано после простого управления версиями документов с помощью CouchDB )
источник
Ответы:
Первый большой вопрос, когда мы углубимся в это: «Как вы хотите хранить наборы изменений» ?
Мой личный подход будет хранить различия. Поскольку отображение этих различий - это действительно специальное действие, я бы поместил их в другую коллекцию «истории».
Я бы использовал другую коллекцию для экономии места в памяти. Как правило, вам не нужна полная история для простого запроса. Таким образом, сохраняя историю вне объекта, вы также можете хранить ее вне общедоступной памяти при запросе этих данных.
Чтобы упростить свою жизнь, я бы сделал так, чтобы исторический документ содержал словарь различий с метками времени. Что-то вроде этого:
Чтобы сделать мою жизнь действительно легкой, я бы включил эту часть своих объектов DataObjects (EntityWrapper, что угодно), которую я использую для доступа к своим данным. Обычно эти объекты имеют некоторую форму истории, так что вы можете легко переопределить
save()
метод, чтобы сделать это изменение одновременно.ОБНОВЛЕНИЕ: 2015-10
Похоже, что теперь есть спецификация для обработки различий JSON . Это кажется более надежным способом хранения различий / изменений.
источник
changes
действительно легко:db.hist.update({_id: ID}, {$set { changes.12345 : CHANGES } }, true)
это приведет к упадку, который изменит только необходимые данные. Mongo создает документы с «буферным пространством» для обработки этого типа изменений. Он также следит за тем, как изменяются документы в коллекции, и изменяет размер буфера для каждой коллекции. Поэтому MongoDB предназначен именно для этого типа изменений (добавление нового свойства / push в массив).Существует схема управления версиями под названием «Vermongo», которая затрагивает некоторые аспекты, которые не были рассмотрены в других ответах.
Одна из этих проблем - одновременные обновления, другая - удаление документов.
Vermongo хранит полные копии документов в теневой коллекции. В некоторых случаях это может привести к чрезмерным накладным расходам, но я думаю, что это также упрощает многие вещи.
https://github.com/thiloplanz/v7files/wiki/Vermongo
источник
Вот еще одно решение с использованием одного документа для текущей версии и всех старых версий:
data
содержит все версии.data
Массив упорядоченный , новые версии будут только получить$push
эд до конца массива.data.vid
это идентификатор версии, который является инкрементным числом.Получить самую последнюю версию:
Получить конкретную версию можно
vid
:Возврат только указанных полей:
Вставить новую версию: (и предотвратить одновременную вставку / обновление)
2
являетсяvid
текущей последней версии и3
является новой версией будут вставлены. Потому что вам нужно самая последняя версия - хvid
, это легко сделать , получить следующую версию - хvid
:nextVID = oldVID + 1
.$and
Условие гарантирует, что2
является последнейvid
.Таким образом, нет необходимости в уникальном индексе, но логика приложения должна заботиться о приращении при
vid
вставке.Удалить конкретную версию:
Это оно!
(помните 16 МБ на лимит документа)
источник
Если вы ищете готовое решение -
Mongoid имеет встроенную простую версию
http://mongoid.org/en/mongoid/docs/extras.html#versioning
mongoid-history - плагин Ruby, который предоставляет значительно более сложное решение с проверкой, отменой и повторением
https://github.com/aq1018/mongoid-history
источник
Я работал над этим решением, которое поддерживает опубликованные, черновые и исторические версии данных:
Я объясняю модель далее здесь: http://software.danielwatrous.com/representing-revision-data-in-mongodb/
Для тех, кто может реализовать нечто подобное в Java , вот пример:
http://software.danielwatrous.com/using-java-to-work-with-versioned-data/
Включая весь код, который вы можете раскошелиться, если хотите
https://github.com/dwatrous/mongodb-revision-objects
источник
Если вы используете mongoose, я обнаружил, что следующий плагин является полезной реализацией формата JSON Patch
Мангуст-патч-истории
источник
Другой вариант - использовать плагин mongoose-history .
источник
Я использовал приведенный ниже пакет для проекта meteor / MongoDB, и он хорошо работает, главное преимущество в том, что он хранит историю / ревизии в массиве в том же документе, поэтому нет необходимости в дополнительных публикациях или промежуточном программном обеспечении для доступа к истории изменений , Он может поддерживать ограниченное количество предыдущих версий (например, последние десять версий), а также поддерживает конкатенацию изменений (поэтому все изменения, произошедшие в течение определенного периода, будут охватываться одной ревизией).
nicklozon / Метеор-коллекция-пересмотры
Другой вариант звука - использовать Метеор Вермонго ( здесь )
источник