使用Java中的变更流进行MongoDB审核

时间:2019-04-12 09:17:22

标签: java mongodb auditing

我正在尝试审核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
}

0 个答案:

没有答案