使用MongoDB $ set更新多个子文档

时间:2018-12-26 22:20:36

标签: mongodb meteor mongodb-query

我有这样的文章文档:

{
    "_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"
];

因此,我尝试为“行”更新属性“ 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”)。 有任何想法吗?谢谢! :)

2 个答案:

答案 0 :(得分:1)

  

'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
            }
        }
    );
}

答案 1 :(得分:1)

您可以使用$ []。这仅适用于 MongoDB 3.6版及更高版本。

引用链接:   https://docs.mongodb.com/manual/reference/operator/update/positional-all/

 You can also see this stackoverflow question reference: 

How to add new key value or change the key's value inside a nested array in MongoDB?

您可以在函数中转换以下查询

 db.col.update(
  { '_id':"rNiwdR8tFwbTdr2oX", },
  { $set: { "lines.$[elem].text" : "hello" } },     
  {  arrayFilters: [ { "elem.id": { $in: lineIds } } ],
  multi: true
 })