【mongoose】save方法报错

数据如下:
{
    array: [
        {
            _id: 'aaa'
            sub_array: [
                {
                    _id: 'saaa',
                    name: 'aaa'
                },
                {...}
            ]
        },
        {...}
    ]
}

现在我要更新sub_arrayname值:

Model.findOne({
    'array._id': 'aaa'
},{'array.$': 1}).then(respon=> {
    let checkdt = respon.array[0].sub_array.find((item)=> {
        reruen item._id == 'saaa'
    })
    checkdt.name = 'new val'
    respon.save().then(r=> res.send(r)).catch(er=> res.send(er))
})

结果报错:

{
    "message": "For your own good, using `document.save()` to update an array which was selected using an $elemMatch projection OR populated using skip, limit, query conditions, or exclusion of the _id field when the operation results in a $pop or $set of the entire array is not supported. The following path(s) would have been modified unsafely:\n  questions.0.sub_questions.1.score\n  questions.0.sub_questions.1.title\nUse Model.update() to update these arrays instead.",
    "name": "DivergentArrayError"
}

为什么会这样?我该怎么修改?

阅读 3.7k
2 个回答

搜一下其实有人问过的:https://stackoverflow.com/que...
mongoose的github上也对这个问题有描述:issues#1334
简单地说,你用findOne的时候用了投影{'array.$': 1},所以返回的文档中只有原始文档的一部分。而save方法是把你给的文档原样存回去,这显然不是你想要的结果,因为会丢数据。举例:

rs0:PRIMARY> db.test.insert({a: 1, b: 2})
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.find()
{ "_id" : ObjectId("5a741072979a928dbe90341a"), "a" : 1, "b" : 2 }
rs0:PRIMARY> var doc = db.test.findOne({}, {a: 1})
rs0:PRIMARY> db.test.save(doc)
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
rs0:PRIMARY> db.test.find()
{ "_id" : ObjectId("5a741072979a928dbe90341a"), "a" : 1 }

说白了,mongoose是在防止你自残,还是挺有节操的,业界良心。

你用的是mongoose?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进