原子更新或推送元素
我在MongoDB中有以下文档。
{
"_id" : ObjectId("521aff65e4b06121b688fabc"),
"user" : "abc",
"servers" : [
{
"name" : "server1",
"cpu" : 4,
"memory" : 4
},
{
"name" : "server2",
"cpu" : 6,
"memory" : 6
},
{
"name" : "server3",
"cpu" : 8,
"memory" : 8
}
]
}
基于某些事件,我必须更新现有服务器的cpu和内存字段,或者在阵列中不存在新增服务器的情况下添加新的服务器。 目前,我正在分两步执行此操作。 首先检查服务器是否已经存在于阵列中。 如果是,请更新cpu和内存字段。 否则,在阵列中推入一个新的子文档。 由于应用程序的多线程性质,有时会将相同的服务器多次添加到阵列。 是否有任何原子操作符执行以下两个操作(类似于$setOnInsert
运算符):
注意:运算符$addToSet
在上述情况下不起作用,因为cpu或内存的值可能不同。
我认为你可以使用findAndModify()来做到这一点,因为它提供了原子更新。 但是你的文档结构不合适。 如果您可以将文档更改为此(即serverID成为阵列的关键字):
{
"_id" : ObjectId("521aff65e4b06121b688fabc"),
"user" : "abc",
"servers" : {
"server1" : {
"cpu" : 4,
"memory" : 4
},
"server2" : {
"cpu" : 6,
"memory" : 6
},
"server3" : {
"cpu" : 8,
"memory" : 8
},
}
}
然后,您可以使用一个原子命令findAndModify()来更新,而无需使用两个单独的find()和update() :
db.collection.findAndModify
(
{query:
{"_id" : ObjectId("521aff65e4b06121b688fabc")},
update:
{$set: {"servers.server4": {"cpu":5, "memory":5 }}},
new: true}
)
当使用这个时,如果servers.server4不存在,它将被插入,否则更新。
MongoDb已经对单个文档进行了原子操作。 因此,就同时发送2条命令到数据库而言,您可以直接从盒子中覆盖。
无论如何,当这两个命令矛盾时,你的问题就会出现。 IE如果你用同一个对象发送两个更新,Mongo的个人文档atmoicness不会帮助你。 所以你需要做的是管理你的应用程序的多线程,这样它就不会发送可能冲突的多个Mongo命令。
链接地址: http://www.djcxy.com/p/61953.html上一篇: atomic update or push element
下一篇: How to atomically update two documents in a collection in MongoDB