更新混合类型的猫鼬嵌套数组

时间:2020-06-16 18:53:43

标签: node.js mongodb express mongoose mongodb-query

我有一个混合类型的猫鼬模式,如下所示:

const user = mongoose.Schema({
    ...
    "links" : []
    ...

填充此架构后,我得到的数据如下:

[
    [
        {
            "step1": "post-url-google", // This field is unique for each entry
            "step2": {
                "title": "Heading 1",
                "likes": 4
            }
        },
    ],

    [
        {
            "step1": "post-url-microsoft",
            "step2": {
                "title": "Heading 1",
                "likes": 1
            }
        },

        {
            "step1": "post-url-apple",
            "step2": {
                "title": "Heading 2",
                "likes": 6 // I want to update this to 7
            }
        }
    ]
]

我想要实现的是将"step1": "post-url-apple"字段从6更新为likes为7 所以我尝试像这样使用User.save()函数:

let user = await User.findOne({"_id" : "some_id"})

user.links[1].some(object => {
    if (object.step1 === "post-url-apple") {
        object.step2.likes = 7
        (async function (){
            user.save() // I also did error handling
        })()
        return
    }
})

此方法可以正常工作,并且用户得到了更新,但由于我在代码的其他部分对同一用户实例并行调用ParallelSaveError函数,因此它不断抛出save() >

所以我决定使用User.findOneAndUpdate()方法,但是使用mongodb点表示法$[<identifier>]时我的查询仍然失败,显然是因为我不知道如何正确使用它。

像这样:

let update = {
    "$set" : { 
        "links.$[index1].$[index2].step2.likes" : 7,
    }
}

let conditions = {
    arrayFilters : [
        {"index1" : 1},
        {"index2.step1" : "post-url-apple"}
    ]
}

try {
    let result = await Users.findOneAndUpdate({"_id" : "some_id"}, update, conditions)
    console.log(result)
} catch (err) {
    console.log(err)
}

出于所有充分的理由,我没有遇到问题,但更新同样没有成功

如何使用"step1": "post-url-apple"likes findOneAndUpdate字段更新为7?

谢谢。

1 个答案:

答案 0 :(得分:1)

arrayFilters中,您应该定义要应用于所有数组元素而不是索引的条件

如果确定,您总是更新外部数组的第二个数组元素(索引= 1),则可以对外部数组使用点表示法,对于内部数组可以使用数组过滤器获取具有step1 = 'post-url-apple'

的元素

您的代码可能看起来像这样

let update = {
    "$set" : { 
        'links.1.$[item].step2.likes': 7 // here we used links.1 to access the second element of the outer array
    }
}

let conditions = {
    arrayFilters : [
        { 'item.step1' : 'post-url-apple' } // item here is the element in the inner array that has step1 = post-url-apple
    ]
}

然后执行更新查询

希望有帮助