在 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"
上下文:
- Spring 使用了数据 MongoDB 并且更新文档导致了以下问题。
问题:
执行更新操作后,集合中的文档丢失了所有数据,只保留了 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
上调用的 如果要设置的值是否可用,只要值可用似乎就可以正常工作set
在 update
上被调用。如果无法设置值,则不会在 Update
上调用 set
来设置值,这会将其作为替换并替换集合中的整个文档。
上下文:
- Spring 使用了数据 MongoDB 并且更新文档导致了以下问题。
问题:
执行更新操作后,集合中的文档丢失了所有数据,只保留了 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
上调用的 如果要设置的值是否可用,只要值可用似乎就可以正常工作set
在 update
上被调用。如果无法设置值,则不会在 Update
上调用 set
来设置值,这会将其作为替换并替换集合中的整个文档。