在 Spring MongoDB 更新中,MonogDB 文档 replaced/lost 字段变为空,此更新的操作日志 "o" 没有 $set,$unset,只有 objectId,如 [=11] =]

In Spring MongoDB update, MonogDB doc replaced/lost fields, becomes empty, oplog "o" for this update has no $set, $unset, has only objectId as in "o2"

上下文:

问题:

执行更新操作后,集合中的文档丢失了所有数据,只保留了 ObjectId

检查 oplog 条目发现一个异常值,了解 o2 字段 ObjectId 表示要更新的对象, o 字段表示操作 performed/updated.

在此特定实例中,o2字段具有预期值,但 o 字段也具有相同的值,而不是要完成的更新操作详细信息。

问题:

知道什么时候我们可以期待下面提到的 oplog 而没有 $set$unset 进行更新操作吗?

此操作后,集合中 ObjectId 的实际文档丢失了除 ObjectId 之外的所有字段。

{
        "ts" : Timestamp(1596778564, 9),
        "t" : NumberLong(7),
        "h" : NumberLong(0),
        "v" : 2,
        "op" : "u",
        "ns" : "db.collectionName",
        "ui" : UUID("2947862a-8fb7-4342-87d1-a0ab5f8bc0bd"),
        "o2" : {
                "_id" : ObjectId("5f27e94e0174081a3feb5c6b")
        },
        "wall" : ISODate("2020-08-07T05:36:04.402Z"),
        "lsid" : {
                "id" : UUID("cbd4b90f-1bff-4ad1-b4e2-4c286fc25450"),
                "uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
        },
        "txnNumber" : NumberLong(1269),
        "stmtId" : 0,
        "prevOpTime" : {
                "ts" : Timestamp(0, 0),
                "t" : NumberLong(-1)
        },
        "o" : {
                "_id" : ObjectId("5f27e94e0174081a3feb5c6b")
        }
}

几毫秒前同一对象的更新oplog如下所示。哪个有正确的操作集。

{
        "ts" : Timestamp(1596778564, 8),
        "t" : NumberLong(7),
        "h" : NumberLong(0),
        "v" : 2,
        "op" : "u",
        "ns" : "db.collectionName",
        "ui" : UUID("2947862a-8fb7-4342-87d1-a0ab5f8bc0bd"),
        "o2" : {
                "_id" : ObjectId("5f27e94e0174081a3feb5c6b")
        },
        "wall" : ISODate("2020-08-07T05:36:04.398Z"),
        "lsid" : {
                "id" : UUID("cbd4b90f-1bff-4ad1-b4e2-4c286fc25450"),
                "uid" : BinData(0,"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=")
        },
        "txnNumber" : NumberLong(1268),
        "stmtId" : 0,
        "prevOpTime" : {
                "ts" : Timestamp(0, 0),
                "t" : NumberLong(-1)
        },
        "o" : {
                "$v" : 1,
                "$set" : {
                        .....
                       .......
                      ......... //All the values to be updated
                }
        }
}

您的一个应用程序正在提供 https://docs.mongodb.com/manual/reference/method/db.collection.update/ 中所述的“替换文件”。替换文档仅包含删除其他字段的 _id。您引用的oplog条目没有任何异常。

希望它也能像我一样帮助面临 Spring-MongoDB 的人。

尝试了以下代码,当 mongoTemplate.updateFirst 中使用的 update 在调用时未设置任何值时会发生这种情况。如果行 update.set 未被注释,则工作正常。当update什么都不设置的时候,就把它当作替换文件。

@Override
    public void run(String... args) throws Exception {
        customerRepository.deleteAll();

        customerRepository.save(new Customer("Bob","S"));
        customerRepository.save(new Customer("Alice","Smith"));

        findAll();

        Update update = new Update();
//      update.set("firstName", "Bobby");

        Query query = Query.query(Criteria.where("lastName").is("S"));
        mongoTemplate.updateFirst(query, update, "customer");

        findAll();
    }

进一步检查我们的代码,发现 set 是根据条件在 update 上调用的 如果要设置的值是否可用,只要值可用似乎就可以正常工作setupdate 上被调用。如果无法设置值,则不会在 Update 上调用 set 来设置值,这会将其作为替换并替换集合中的整个文档。