使用 MongoDB $set 更新多个子文档
Using MongoDB $set to update multiple subdocuments
我有这样的文章文档:
{
"_id" : "rNiwdR8tFwbTdr2oX",
"createdAt" : ISODate("2018-08-25T12:23:25.797Z"),
"title" : "Happy",
"lines" : [
{
"id" : "5efa6ad451048a0a1807916c",
"text" : "Test 1",
"align" : "left",
"indent" : 0
},
{
"id" : "ae644f39553d46f85c6e1be9",
"text" : "Test 2"
},
{
"id" : "829f874878dfd0b47e9441c2",
"text" : "Test 3"
},
{
"id" : "d0a46ef175351ae1dec70b9a",
"text" : "Test 4"
},
{
"id" : "9bbc8c8d01bc7029220bed3f",
"text" : "Test 5"
},
{
"id" : "6b5c02996a830f807e4d8e35",
"text" : "Test 6",
"indent" : 0
}
]
}
我需要更新一些线路。
例如,我有一个数组,其中包含必须更新的行的 ID。
let lineIds = [
"5efa6ad451048a0a1807916c",
"829f874878dfd0b47e9441c2",
"6b5c02996a830f807e4d8e35"
];
因此,我尝试更新 "lines" 的属性 "attr",然后执行以下操作:
'articles.updateLines': function (articleId, lineIds, attr, value) {
return Articles.update({
'_id': articleId,
'lines.id': { $in: lineIds }
},
{
$set: {
['lines.$.' + attr]: value
}
},
{ multi: true }
);
}
问题是只更新了第一行(id="5efa6ad451048a0a1807916c")。
有任何想法吗?谢谢! :)
'lines.id': { $in: lineIds }
这行不通,因为 lines
是一个数组。
我从你的问题中了解到,你可以准备一个经过适当处理的新数组,并将 lines
数组替换为新数组。这是一个如何做到这一点的想法:
'articles.updateLines': function (articleId, lineIds, attr, value) {
let lines = Articles.findOne(articleId).lines;
// prepare a new array with right elements
let newArray = [];
for(let i=0; i<lines.length; i++){
if(lineIds.includes(lines[i].id)){
newArray.push(value)
}
else newArray.push(lines[i])
}
return Articles.update({
'_id': articleId,
},
{
$set: {
lines: newArray
}
}
);
}
您可以使用$[]。这仅适用于 MongoDB 版本 3.6 及更高版本。
参考link:
https://docs.mongodb.com/manual/reference/operator/update/positional-all/
You can also see this Whosebug question reference:
您可以在函数中转换以下查询
db.col.update(
{ '_id':"rNiwdR8tFwbTdr2oX", },
{ $set: { "lines.$[elem].text" : "hello" } },
{ arrayFilters: [ { "elem.id": { $in: lineIds } } ],
multi: true
})
我有这样的文章文档:
{
"_id" : "rNiwdR8tFwbTdr2oX",
"createdAt" : ISODate("2018-08-25T12:23:25.797Z"),
"title" : "Happy",
"lines" : [
{
"id" : "5efa6ad451048a0a1807916c",
"text" : "Test 1",
"align" : "left",
"indent" : 0
},
{
"id" : "ae644f39553d46f85c6e1be9",
"text" : "Test 2"
},
{
"id" : "829f874878dfd0b47e9441c2",
"text" : "Test 3"
},
{
"id" : "d0a46ef175351ae1dec70b9a",
"text" : "Test 4"
},
{
"id" : "9bbc8c8d01bc7029220bed3f",
"text" : "Test 5"
},
{
"id" : "6b5c02996a830f807e4d8e35",
"text" : "Test 6",
"indent" : 0
}
]
}
我需要更新一些线路。 例如,我有一个数组,其中包含必须更新的行的 ID。
let lineIds = [
"5efa6ad451048a0a1807916c",
"829f874878dfd0b47e9441c2",
"6b5c02996a830f807e4d8e35"
];
因此,我尝试更新 "lines" 的属性 "attr",然后执行以下操作:
'articles.updateLines': function (articleId, lineIds, attr, value) {
return Articles.update({
'_id': articleId,
'lines.id': { $in: lineIds }
},
{
$set: {
['lines.$.' + attr]: value
}
},
{ multi: true }
);
}
问题是只更新了第一行(id="5efa6ad451048a0a1807916c")。 有任何想法吗?谢谢! :)
'lines.id': { $in: lineIds }
这行不通,因为 lines
是一个数组。
我从你的问题中了解到,你可以准备一个经过适当处理的新数组,并将 lines
数组替换为新数组。这是一个如何做到这一点的想法:
'articles.updateLines': function (articleId, lineIds, attr, value) {
let lines = Articles.findOne(articleId).lines;
// prepare a new array with right elements
let newArray = [];
for(let i=0; i<lines.length; i++){
if(lineIds.includes(lines[i].id)){
newArray.push(value)
}
else newArray.push(lines[i])
}
return Articles.update({
'_id': articleId,
},
{
$set: {
lines: newArray
}
}
);
}
您可以使用$[]。这仅适用于 MongoDB 版本 3.6 及更高版本。
参考link: https://docs.mongodb.com/manual/reference/operator/update/positional-all/
You can also see this Whosebug question reference:
您可以在函数中转换以下查询
db.col.update(
{ '_id':"rNiwdR8tFwbTdr2oX", },
{ $set: { "lines.$[elem].text" : "hello" } },
{ arrayFilters: [ { "elem.id": { $in: lineIds } } ],
multi: true
})