Я новичок в MongoDB. Я ищу способ зарегистрировать все операции, которые вставляют, обновляют или удаляют документы в целях сохранения истории изменений. Так, например, я хотел бы знать, когда было обновлено определенное поле в конкретном документе, что оно было обновлено и что было раньше. Это для приложения ASP.NET C# с использованием драйвера C# MongoDB, поэтому я не возражаю против того, включает ли это только сам Mongo или код C#.Запись, обновление и удаление операций в MongoDB
Пример:
ID |Timestamp |Operation|ObjectID | PrevValue | NewValue
-----------------------------------------------------------------------------------------------
2153|1411390359| i |245245...| null |{name: "John Smith", age: 35}
2154|1411390471| u |245245...| {age: 35} | {age: 36}
2155|1411390478| d |245245...|{name: "John Smith", age: 36}| null
Он не должен следовать этому точному формату, но он должен облегчить отслеживание истории.
Я взглянул на MongoDB oplog, но он, похоже, не подходит для такого рода работ. Чтобы определить изменения в документе, например, мне кажется, что я должен искать две записи (самая последняя запись обновления для документа и предыдущая запись документа, которая может быть обновлением или вставкой), а затем сравнить каждое поле в документе, чтобы проверить, какие из них были изменены и каковы их первоначальные значения. Я бы предпочел просто иметь одну запись, которая содержит всю эту информацию ради эффективности, в случае, если требуется много запросов для изучения изменений во многих документах. Я хочу убедиться, что использование журнала настолько безболезненным, насколько возможно. Было бы также идеально, если бы журнал был сохранен в коллекции MongoDB с документом для каждой записи (например, с помощью oplog), чтобы упростить запрос.
Есть ли функция в MongoDB (кроме oplog), которая может выполнить что-то вроде этого? Если нет, есть ли хороший сторонний инструмент, который может? Или я должен реализовать его вручную?
EDIT: Несколько подробнее:
1) Еще одна проблема, с oplog является то, что ограничен, поэтому он удаляет старые записи, когда он бежит из космоса. Я хотел бы сохранить список всю историю независимо от того, сколько ей лет.
2) Содержимое журнала будет отображаться каким-либо образом пользователю, который может запросить историю изменений. Это относится не только к внутренним записям администраторов БД, поэтому их необходимо запрашивать по требованию.
EDIT # 2: Я занимался мозговым штурмом некоторых решений этой проблемы, но все они все еще имеют некоторые недостатки, поэтому я был бы признателен за дальнейший ввод, если у кого-то есть лучшая идея.
Возможное решение 1: Ведение отдельного документа для каждой версии (с версией #) и флаг, если он был удален.
Реализация: добавьте поле «версия» к каждому документу. Версия 1 - это начальное состояние (представляет собой вставку), а последующие версии представляют собой обновления, которые помещаются в отдельные вновь созданные документы, а не обновляются старые. Версия -1 означает, что документ теперь считается «удаленным». Очевидно, что это не связано с фактическим файлом журнала.
Проблемы: требуется много места и дорогостоящий запрос, если мне нужно загрузить данные исторических изменений для многих документов одновременно. Также трудно определить, какие конкретные поля были изменены, если я также не включил поле «Изменения» из предыдущей версии, что также добавляет больше места. Также может быть беспорядочным и дорогостоящим для запросов через новейшие версии, если нужно искать более старые версии (не указывать, какая версия является текущей). Даже имея еще один флаг, говорящий, что он является текущим, мне нужно было бы убедиться, что флаг обновляется все время по мере необходимости.
Возможное решение 2: Ведение истории изменений для каждого документа в поле поддокументе
реализации: Каждый документ имеет поле «RevisionHistory», который содержит каждую ревизию с номером версии. Легче искать исторические данные для отдельных документов
Проблемы: сложнее выполнить поиск истории по нескольким документам, а любые вызовы API для выполнения обновлений сложнее из-за нового поля. В частности, мне нужно будет показать все изменения за прошлые X часов (X предоставлен пользователем) в рамках реализации, что потребует сканирования всех документов, если этот подход используется.
Возможное решение 3: Добавление вручную Вход вызова() из C#
Реализация: Каждый раз, когда MongoDB C# Driver API вызывается с новой операцией, есть программист также добавить строку призванию специальную функцию для ведения журнала в файл журнала.
Проблемы: Зависит от того, что программист действительно помнит, как добавить этот вызов функции вручную и правильно его называть. Одна простая ошибка приводит к тому, что система каротажа становится ненадежной.
Возможное решение 4: Создать функцию-оболочку для операций API из C#
реализации: Программисты не вызывать API напрямую, но вызвать функцию, которая обрабатывает работу за них. Это требует большой работы, обрабатывая все возможные типы вызовов API на уровне функции-оболочки, но является последовательным и надежным. Хороший способ абстрагировать доступ к БД, чтобы что-то не сломалось с неправильным вызовом API низкого уровня. Кто-то, не работающий над DAL, может просто вызвать функцию обертки, и функция определяет детали, включая ведение журнала.
Проблемы: Функция обертки более сложна для разработки, поскольку она требует учета всех возможных вызовов API, которые изменяют документ.
Сейчас я склоняюсь к решению 4. Но опять же, если есть более простой способ сделать это, мне интересно услышать его.