很遗憾,这不能在使用 upsert 或类似名称的单个更新语句中完成。
这可以使用从 MongoDB 3.2 开始支持的bulkWrite() 来实现。
您还可以使用 MongoDB 4.2 中的新 update() 命令 - 请注意,这仅在 4.2 中可用。
更新命令现在允许多个更新语句。虽然您可能需要运行两个更新命令,但您只需发送一次命令并让 MongoDB 为您批处理语句。
根据您的要求,您可以尝试以下操作,首先尝试使用 $ positional 运算符更新数组中的相关元素。
然后我们使用$addToSet 数组运算符,它将尝试添加一个新的数组元素 - 仅当没有找到匹配的数组元素非常适合我们在步骤 1 中无法进行更新的场景.
两种解决方案都适用于您的场景。
使用 bulkWrite()
db.getCollection("tests").bulkWrite([
{
updateOne: {
filter: {link: "abc.com", "Values.valueID": "v2"},
update: {$set: {"Values.$.value": "xyz"}}
}
},
{
updateOne: {
filter: {link: "abc.com"},
update: {
$addToSet: {
"Values": {
"valueID": "v2",
"date": "05-07-2015",
"value": "xyz"
}
}
}
}
}
]);
使用新的 update() 命令:
db.runCommand(
{
update: "tests",
updates: [
{
q: {link: "abc.com", "Values.valueID": "v2"},
u: {$set: {"Values.$.value": "xyz"}}
},
{
q: {link: "abc.com"},
u: {
$addToSet: {
"Values": {
"valueID": "v2",
"date": "05-07-2015",
"value": "xyz"
}
}
}
}
],
ordered: false,
writeConcern: {w: "majority", wtimeout: 5000}
}
)
样本数据:
db.getCollection("tests").insertMany([{
"link": "abc.com",
"Values": [
{
"valueID": "v1",
"date": "05-07-2015",
"value": "10"
}
]
},
{
"link": "def.com",
"Values": [
{
"valueID": "v1",
"date": "05-07-2015",
"value": "1"
}
]
}]
);
不存在时插入数组:
db.runCommand(
{
update: "tests",
updates: [
{
q: {link: "abc.com", "Values.valueID": "v2"},
u: {$set: {"Values.$.value": "xyz"}}
},
{
q: {link: "abc.com"},
u: {
$addToSet: {
"Values": {
"valueID": "v2",
"date": "05-07-2015",
"value": "xyz"
}
}
}
}
],
ordered: false,
writeConcern: {w: "majority", wtimeout: 5000}
}
)
结果:
{
"_id" : ObjectId("5dd8164969f4361ce9821b88"),
"link" : "abc.com",
"Values" : [
{
"valueID" : "v1",
"date" : "05-07-2015",
"value" : "20"
},
{
"valueID" : "v2",
"date" : "05-07-2015",
"value" : "xyz"
}
]
}
更新现有值:
db.runCommand(
{
update: "tests",
updates: [
{
q: {link: "abc.com", "Values.valueID": "v2"},
u: {$set: {"Values.$.value": "new value"}}
},
{
q: {link: "abc.com"},
u: {
$addToSet: {
"Values": {
"valueID": "v2",
"date": "05-07-2015",
"value": "new value"
}
}
}
}
],
ordered: false,
writeConcern: {w: "majority", wtimeout: 5000}
}
)
结果:
{
"_id" : ObjectId("5dd8164969f4361ce9821b88"),
"link" : "abc.com",
"Values" : [
{
"valueID" : "v1",
"date" : "05-07-2015",
"value" : "20"
},
{
"valueID" : "v2",
"date" : "05-07-2015",
"value" : "new value"
}
]
}