【问题标题】:Updating mongoose nested array of mixed types更新混合类型的猫鼬嵌套数组
【发布时间】:2020-10-06 11:35:51
【问题描述】:

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

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 更新为具有 7 的 likes 所以我尝试像这样使用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)
}

出于所有充分的理由,我没有点击 catch 块,但更新同样不成功

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

谢谢。

【问题讨论】:

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


    【解决方案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
        ]
    }
    

    然后进行更新查询

    希望对你有帮助

    【讨论】:

    • 我试过了,但仍然是同样奇怪的结果。显然问题出在我代码的其他部分,而不是您给出的逻辑。我会弄清楚代码的哪些部分导致了奇怪的行为。谢谢。
    • 我已经通过某种方式跟踪并将索引传递给更新函数解决了这个问题,如下所示:'links.1.indexPassedToUpdateFunction.step2.likes': 7 where indexPassedToUpdateFunction = <Number>
    猜你喜欢
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 2021-04-14
    • 2022-01-26
    • 2017-05-19
    • 2018-09-13
    • 2018-10-30
    相关资源
    最近更新 更多