mongodb - 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"
问题描述
Context:
- Spring Data MongoDB is used and updating a document caused the following issue.
Issue :
After an update operation performed, document in collection lost all the data and kept only ObjectId
in it.
Checking the oplog
entry found an unusual value, understand that the o2
field ObjectId
says the object to be updated and o
field says about operations being performed/updated.
In this particular instance o2
field has the expected value, but o
field also has the same value instead of the update operation details to be done.
Question :
Any idea when can we expect such an oplog
as mentioned below without $set
or $unset
for update operations ?
After this operation, actual document with ObjectId
in collection lost all the fields except 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")
}
}
The update oplog
for the same object few milliseconds ago is given below. Which has the right set of operations.
{
"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
}
}
}
解决方案
希望它也像我一样对 Spring-MongoDB 中的一些人有所帮助。
尝试了以下代码,在调用时未设置任何值时会发生这种update
情况mongoTemplate.updateFirst
。如果该行update.set
未注释,则可以正常工作。当更新中没有设置任何内容时,它将它作为替换文档。
@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
CONDITION IF 要设置的值是否可用,它似乎工作正常,只要这些值可用并且set
被调用update
。如果值不可设置,set
则不调用Update
设置值,将其作为替换并替换集合中的整个文档。
推荐阅读
- python - Django rest框架中ViewSet和GenericViewSet的区别
- mysql - 运行多个进程时MySQL连接被拒绝
- google-apps-script - 如何在 YouTube 数据 API 中每次执行搜索功能时获得新结果
- android - 作为 Android 源代码构建的一部分,如何启用触摸唤醒?
- graphql - 围绕 Apollo Query 组件重新渲染的规则是什么?
- ibm-integration-bus - 如何在 IIB 中创建一个变量,该变量具有每个单个流的范围?
- php - 在 Laravel 中将旧电子邮件更改为新电子邮件的困难
- javascript - Map an array of objects using javascript, it returns an undefine values
- apache-spark - spark - 避免冗长模式的 stackoverflow 错误
- javascript - 如何通过比较两个不同的独特属性来对不同大小的对象数组中的元素进行分组?在javascript中