我正在尝试审核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}
我还尝试使用mongo模板创建自己的更新。
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));
}
}
我的TestObject:
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
}