我在MongoDB集合中有以下字段的文档:
var doc = {
container_id:12,
steps: [
{
name:'name1',
},
{
name:'name2',
}
]
}
我需要查找所有包含container_id == 12以及最后一步'步骤的文档。元素匹配&name;' name2'并使用新值更新它。
我尝试了以下内容:
let findQ = {'container_id': 12, "steps:{$slice:-1}.name": "name2"};
let updateQ = {"$set": {'steps.$.name': "new name3"}};
db.collection(myCollection).update(
findQ,
updateQ,
{multi: true},
function (err, doc) { ... }
);
答案 0 :(得分:0)
您需要在语句的查询部分添加$where
条件,以确保文档包含“last”位置中的数组匹配。但这只是一个“附加”约束,而“位置”应该从"steps.name": "name2"
的标准查询选项获得:
所以给出样本文件:
/* 1 */
{
"_id" : ObjectId("59c39cf859f55d64d6e30293"),
"container_id" : 12.0,
"steps" : [
{
"name" : "name1"
},
{
"name" : "name2"
}
]
}
/* 2 */
{
"_id" : ObjectId("59c39d1b59f55d64d6e30294"),
"container_id" : 12.0,
"steps" : [
{
"name" : "name1"
},
{
"name" : "name2"
},
{
"name" : "name3"
}
]
}
发出查询:
db.collection('junk').update(
{
"container_id": 12,
"steps.name": "name2",
"$where": "this.steps.slice(-1)[0].name === 'name2'"
},
{ "$set": { "steps.$.name": "new name4" } },
{ "multi": true }
)
结果:
/* 1 */
{
"_id" : ObjectId("59c39cf859f55d64d6e30293"),
"container_id" : 12.0,
"steps" : [
{
"name" : "name1"
},
{
"name" : "new name4"
}
]
}
/* 2 */
{
"_id" : ObjectId("59c39d1b59f55d64d6e30294"),
"container_id" : 12.0,
"steps" : [
{
"name" : "name1"
},
{
"name" : "name2"
},
{
"name" : "name3"
}
]
}
因此第二个文档虽然包含匹配值为"name2"
的数组元素,但却被$where
子句排除,因为它不是数组中的最后一个元素。
只有第一个文档会更新,因为它符合两个条件。
注意:您仍然需要
"steps.name": "name2"
的查询部分中的.update()
才能获得positional$
operator的排名。如果数组中实际上有多个匹配项用于相同的值,则此时无法执行此操作。 See How to Update Multiple Array Elements in MongoDB了解有关多场比赛的详细信息。
答案 1 :(得分:0)
根据上述问题的描述,请尝试在MongoDB shell中执行以下更新操作。
db.myCollection.update({
"container_id": 12.0,
steps: {
$elemMatch: {
"name": "name2"
}
}
}, {
$set: {
'steps.$.name': 'name3'
}
}, {
multi: true
}
)