使用 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
 })