我有一些 mongodb 文档,其中有一个名为 states 的数组。下面给出了示例文档。
{ "_id":ObjectId("xxxxxxxxxx"),
"states":[
{"place":"EU","skId":"SK01"},
{"place":"IN","skId":"SK05"},
{"place":"NZ","skId":"SK08"}
]
}
如果我得到一个新对象,如果新对象的“place”键与数组中的键不匹配,则必须将其推入相应文档的 states 数组,否则如果新对象的“place”键匹配对于数组中的任何对象,我必须用新对象替换或更新数组中的该对象。我目前可以将新对象插入数组(情况 1),但无法更新(情况 2)。在下面添加我的代码和预期输出。
案例1 -->
new object --> {"place":"KL","skId":"SK08"}
expected output : { "_id":ObjectId("xxxxxxxxxx"),
"states":[
{"place":"EU","skId":"SK01"},
{"place":"IN","skId":"SK05"},
{"place":"NZ","skId":"SK08"},
{"place":"KL","skId":"SK08"}
]
}
案例2 -->
new object --> {"place":"NZ","skId":"SK01"}
expected output : { "_id":ObjectId("xxxxxxxxxx"),
"states":[
{"place":"EU","skId":"SK01"},
{"place":"IN","skId":"SK05"},
{"place":"NZ","skId":"SK01"}
]
}
我的代码:
var query = {"_id": ObjectId(xxx)}
var arr = [];
db.collection('Regions').find(query).toArray().then((data) => {
arr = data[0]["states"];
const index = arr.findIndex((e) => e.place === reqBody.place);
var obj = {"place":reqBody.place,"skId":reqBody.skId};
if (index > -1) {
arr[index] = obj;
} else {
arr.push(obj);
}
var newStates={"states":arr}
var newStateValue = {$set:newSquad};
db.collection("Regions").updateOne(query, newStateValue, function(err, result) {
if(err){
resolve({
"error": ""+err+"",
"statuscode": "404"
});
}
})
})
您可以在聚合管道中执行以下操作:
$match
过滤您想要的文档$addFields
与 $map
有条件地更新 states
数组中的匹配文档(如果任何数组条目匹配)$setUnion
步骤 2 中的结果,其中输入文档的数组作为未找到数组条目的插入情况$merge
返回原始文档进行更新db.collection.aggregate([
{
$match: {
_id: "objId1"
}
},
{
"$addFields": {
"input": {
"place": "KL",
"skId": "SK08"
}
}
},
{
"$addFields": {
"states": {
"$map": {
"input": "$states",
"as": "s",
"in": {
"$cond": {
"if": {
$eq: [
"$$s.place",
"$input.place"
]
},
"then": "$input",
"else": "$$s"
}
}
}
}
}
},
{
"$addFields": {
"states": {
"$setUnion": [
"$states",
[
"$input"
]
]
}
}
},
{
"$project": {
_id: 1,
states: 1
}
},
{
"$merge": {
"into": "collection",
"on": "_id",
"whenMatched": "replace"
}
}
])
这里是Mongo游乐场供您参考。