Mongodb mongo子文档的pushOrModify-like运算符
我想做的是,如果子文档存在,更新它,否则,只通过一种方法推送新的子文档 首先,找到Mongodb mongo子文档的pushOrModify-like运算符,mongodb,mongodb-query,Mongodb,Mongodb Query,我想做的是,如果子文档存在,更新它,否则,只通过一种方法推送新的子文档 首先,找到{name:“SweetTown”},然后 如果存在Bob,我想将其声誉更改为30: Town collection { name: "SweetTown", residents: [{ name: "Bob", reputation: 20 }] } 应该是 { name: "SweetTown", residents: [{ name: "Bob", reputation: 30 }] } { name:
{name:“SweetTown”}
,然后
如果存在Bob
,我想将其声誉更改为30
:
Town collection
{ name: "SweetTown", residents: [{ name: "Bob", reputation: 20 }] }
应该是
{ name: "SweetTown", residents: [{ name: "Bob", reputation: 30 }] }
{ name: "SweetTown", residents: [
{ name: "Alice", reputation: 140 },
{ name: "Bob", reputation: 30 }
]}
或否,将{name:“Bob”,声誉:30}
推送到居民
Town collection
{ name: "SweetTown", residents: [{ name: "Alice", reputation: 140 }] }
应该是
{ name: "SweetTown", residents: [{ name: "Bob", reputation: 30 }] }
{ name: "SweetTown", residents: [
{ name: "Alice", reputation: 140 },
{ name: "Bob", reputation: 30 }
]}
我对此进行了大量搜索,找到了一些解决方案,如$addToSet
,$push
和$ne
或upsert
选项
但是,我不能正确地混合这些来解决这个问题。如何使其工作?这实际上需要“两个”(或“三个”upsert)update语句,这也是“批量”操作存在的一个很好的原因
db.collection.bulkWrite([
//尝试更新匹配的元素
{“updateOne”:{
“筛选器”:{
“姓名”:“甜心镇”,
“居民姓名”:“鲍勃”
},
“更新”:{
“$set”:{“居民.$.声誉”:30}
}
},
//$将元素推到不匹配的位置
{“updateOne”:{
“过滤器”:{
“姓名”:“甜心镇”,
“residents.name”:{“$ne”:“Bob”}
},
“更新”:{
“$push”:{
“居民”:{“姓名”:“鲍勃”,“声誉”:30}
}
}
}}
])
或者,如果您确实想在“Sweetton”
的基本文档中包含“upsert”
,那么您需要将该问题分离到它自己的测试中:
db.collection.bulkWrite([
//尝试更新匹配的元素
{“updateOne”:{
“筛选器”:{
“姓名”:“甜心镇”,
“居民姓名”:“鲍勃”
},
“更新”:{
“$set”:{“居民.$.声誉”:30}
}
},
//$将元素推到不匹配的位置
{“updateOne”:{
“过滤器”:{
“姓名”:“甜心镇”,
“residents.name”:{“$ne”:“Bob”}
},
“更新”:{
“$push”:{
“居民”:{“姓名”:“鲍勃”,“声誉”:30}
}
}
}},
//仅在实际为upsert时使用$setOnInsert
{“updateOne”:{
“过滤器”:{
“名称”:“糖果城”
},
“更新”:{
“$setOnInsert”:{
“居民”:[{“姓名”:“鲍勃”,“声誉”:30}]
}
},
“向上插入”:正确
}}
])
因此,一般的概念是,只有当“upsert”
实际发生时,才应用该操作。为了确保这只发生在这种情况下,实际查看数组元素的其他操作没有标记为“upsert”
选项。该部分是故意的
无论您以何种方式看待它,只有这些操作中的一个才有可能在数据库中实际进行任何修改,因为要么找到了元素,要么没有找到文档,甚至没有创建新的文档
在任何情况下,都不可能在单个update语句中执行此类操作。但是,由于“批量”操作实际上只是一个请求和一个响应,然后就应用程序而言,只需与服务器进行一次对话,服务器就可以尝试这三种方法并返回响应
对于直接批量API的早期使用,备选语法为:
var bulk=db.collection.initializeOrderedBulkOp();
//$set匹配现有的位置
bulk.find({“name”:“SweetTown”,“residents.name”:“Bob”}).updateOne({
“$set”:{“居民.$.声誉”:30}
});
//$push不存在的地方
bulk.find({“name”:“SweetTown”,“residents.name”:{“$ne”:“Bob”}}).updateOne({
“$push”:{“居民”:{“姓名”:“鲍勃”,“声誉”:30}”
});
//仅尝试向上插入
bulk.find({“name”:“SweetTown”}).upsert().updateOne({
“$setOnInsert”:{
“居民”:[{“姓名”:“鲍勃”,“声誉”:30}]
}
})
bulk.execute();
我原以为可以用findOneAndModify
解决,但这与使用bulkWrite
操作完全不同。当我遇到这样的问题时,它给了我很多机会。谢谢。