Я пытаюсь проверять вставки, обновления и удаления в MongoDB. Поэтому я решил использовать приложение Java с потоками изменений и хранить результаты для каждой коллекции в собственной коллекции.
Я не знаю, является ли это лучшим способом, и я открыт для других предложений. Для меня очень важно, чтобы при обновлении я просто хотел сохранить различия. Вот тут и начинается моя проблема.
Я пытался использовать репозиторий Spring Mongo, но каждый раз, когда я сохраняю свой объект, репозиторий заменяет старый объект.
{doc=Document{{_id=5cb047d9e0da0e87342f5979, name=Testing Object, data=Document{{2019-04-12=0}}, _class=com.TestObject}}, time=2019-04-12T08:10:14, operation=replace}
Я также попытался создать собственное обновление, используя шаблон Монго.
private void update(TestObject testObject){
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
MongoTemplate template = new MongoTemplate(mongoClient, "myDB");
Query query = new Query(new Criteria("_id").is(testObject.getId()));
Update update = new Update();
update.set("name",testObject.getName());
update.set("data", testObject.getData());
template.upsert(query, update,TestObject.class);
}
На этот раз это было обновление и показывалось только обновленное поле, но я добавил только одно значение в поле данных, и оно показало все значения.
{new={"data": {"2019-04-12": {"$numberDecimal": "0"}, "2019-04-13": {"$numberDecimal": "1"}, "2019-04-14": {"$numberDecimal": "2"}}}, removed=[], time=2019-04-12T08:33:33, operation=update}
Есть ли способ получить только те пары ключ-значение, которые были добавлены / удалены?
Мой любимый результат будет:
{new={"data": "2019-04-14": {"$numberDecimal": "2"}}}, removed=[], time=2019-04-12T08:33:33, operation=update}
Мое приложение для аудита:
public static void main(String[] args) {
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = mongoClient.getDatabase("myDB");
MongoDatabase auditDb = mongoClient.getDatabase("audit");
ChangeStreamIterable<Document> changeStreamDocuments = database.watch().fullDocument(FullDocument.DEFAULT);
while (true) {
ChangeStreamDocument<Document> doc = changeStreamDocuments.first();
String collectionName = doc.getNamespace().getCollectionName();
MongoCollection<Document> audit_collection = auditDb.getCollection("audit_" + collectionName);
Map<String, Object> auditDoc = new HashMap<String, Object>();
auditDoc.put("operation", doc.getOperationType().getValue());
int date = doc.getClusterTime().getTime();
LocalDateTime time = LocalDateTime.ofEpochSecond(date, 0, ZoneOffset.UTC);
auditDoc.put("time", time);
Document fullDocument = doc.getFullDocument();
UpdateDescription updateDescription = doc.getUpdateDescription();
if (fullDocument != null) { //insert
auditDoc.put("doc", fullDocument);
} else if (updateDescription != null) { //update
auditDoc.put("new", updateDescription.getUpdatedFields());
auditDoc.put("removed", updateDescription.getRemovedFields());
} else { //delete
auditDoc.put("doc", doc.getDocumentKey());
}
System.out.println(auditDoc);
audit_collection.insertOne(new Document("document", auditDoc));
}
}
Мой тестовый объект:
public class TestObject {
@Id
private ObjectId id;
@Indexed(unique = true)
private String name;
private Map<String, Decimal128> data;
//Constructors, getter and setter would be below
}