Mongoose save 失效?

喜欢踩坑的冷月又踩到了新坑

发现问题

原有的代码简化后长这样

let resp = await schema.billing.findOne({"user": uid});
resp.billing[i].remain = parseInt(remain);
await resp.save();

没毛病对不对, await resp.save() 正确返回了doc, 没有抛出任何exception

但是, mongodb里的信息却一直 没有修改

行吧, 我们先检查下代码, 嗯 没有问题???

解决问题

一番搜索发现有很多同样遭遇的朋友

https://stackoverflow.com/questions/35733647/mongoose-instance-save-not-working/55739214

好了, 他们的方案是这样的

club.members[index].name = new_name;
club.markModified('members');
club.save();

我也试着跟着做修改

let resp = await schema.billing.findOne({"user": uid});
resp.billing[i].remain = parseInt(remain);
// 千万 千万 一定 不要删除下面这行代码, 不然马上飞天
resp.markModified('billing');
await resp.save();

改成这样后, 数据成功保存了

一个不寻根究底的程序员, 不是好的程序员, 我们来寻找这个错误的原因

为什么会发生这种情况

https://mongoosejs.com/docs/schematypes.html

在官方文档中, markModified 多用于对象内部变换 等 无法被hook的场景

但是一个简单的字典肯定可以被hook, 况且也没有特别多人反馈这个问题 (这应该是个很普及的问题), 这应该是我们的问题

回头看我们的定义

const Billing = new mongoose.Schema({
    billing: {}
}, {collection: "xxxxxx"});

难道是我定义不完全?

尝试修改billing定义

const orderSchema = new mongoose.Schema({
    remain: Number
});

const Billing = new mongoose.Schema({
    billing: [orderSchema]
}, {collection: "xxxxxx"});

好的, 现在代码正常了, 我们不需要额外 markModified 了

总结

数据结构定义不完整, 不规范可能导致hook实效

对于key不确定的数据, 我们可以 markModified

对于key固定的数据, 我们应该定好数据格式, 让他更加规范

《Mongoose save 失效?》有28条评论

  1. Greetings! I’ve been following your website for some time now and finally got the bravery to go ahead and give you a shout out from Kingwood Tx! Just wanted to mention keep up the great job!

发表评论

电子邮件地址不会被公开。