【问题标题】:Mongoose instance .save() not working猫鼬实例 .save() 不工作
【发布时间】:2016-06-14 12:06:48
【问题描述】:

我对 Mongoose 和 MongoDb 有疑问

非常有趣的是,只有Model.update 有效,而save 永远不会有效,甚至不会触发回调。

猫鼬:4.4.5 MongoDB:3.0.8

快速路线

var mongoose = require('mongoose');
mongoose.connect("mongodb://127.0.0.1:27017/db");
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function(callback) {
    console.log("connection to db open")
});
var User = require("../models/user.js");

用户模型

var user = new Schema({
    uid: { type: Number, required: true, unique: true},
    hwid: { type: String, default:""},
    bol:{type:String,default:""}
});

更新端点

工作版本:Model.update()

User.update({_id: id}, {
    uid: 5, 
}, function(err, numberAffected, rawResponse) {
    console.log(err);
})

不工作的版本,我必须解决这个问题:Object.save()

User.find({_id:id}, function(err,user){
    if(err){
         console.log(err);
    }
    if(!user){
         console.log("No user");
    }else{
        user.uid = 5;
        user.save(function(err,news){
            console.log("Tried to save...");
        });
    }
    console.log("At least worked");
})

甚至回调也没有触发。连接成功打开。它从不调用回调。


  1. 尝试使用var User = connection.model('User', schema) 无效。

【问题讨论】:

  • 我知道您的评论说它是一个 mongo 对象,但老实说,您所展示的内容无法证明这一点,这最可能是您的 .save 方法没有触发的原因。您如何验证它是从数据库返回的实际实例?
  • @Paul 为您更新了问题
  • 当你 console.log user.find() 回调中会发生什么?
  • @JesseKernaghan 没什么,它没有调用回调。
  • @JesseKernaghan,@Paul 感谢您的帮助,我自己解决了问题。犯了一个新错误。

标签: node.js mongodb mongoose


【解决方案1】:

我也有同样的问题。我的问题是关于更改数据库中的数组,然后当我尝试使用 .save() 时,它不明白我更改了任何内容,然后 .save() 不起作用。 我只是在使用 .save() 之前使用 markModified(),我的问题就解决了。

这是我的代码有问题:(不工作)

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

这是我解决的代码:(工作)

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

享受吧!

【讨论】:

  • 我的问题类似,更改不够明确。不要试图像这样变得聪明:document.keys = { ...document.keys, ...updates } 而是一一应用所有更改
  • 哇,这非常有用!我正在使用 mutator 函数来修改数组的内容,而 Mongoose 并没有选择它们。这个答案结束了长达数小时的 bug 搜寻。
  • 只是附带说明,如果您有像我这样的复杂更新,它也适用于列表(:
  • 还修复了我在更新地图中的某些嵌套属性时遇到的问题
  • 这对我有用。非常感谢!也适用于对象。不仅仅是数组。
【解决方案2】:

我不会删除这个问题,因为人们也可能遇到这个问题。实际上问题与 MongoDb 或 Mongoose 无关。当您调用Object.save() 时,责任链如下:

  1. Schema.pre("保存")
  2. 将数据保存到 dabe
  3. Schema.post("save")

因此,如果您阻止 pre("save") 并且不调用 next() 处理程序,您将无法保存您的文档。这是我的情况,我忘记了 if 语句中的 next() 调用,并试图找到错误超过 3 小时。

user.pre("save", function(next) {
    if(!this.trial){
        //do your job here
        next();
    }
}

this.trial == true 时,下一个处理程序将无法访问。

为防止此类错误,我们应该注意分支覆盖,记者可以向我们展示未经测试的代码。您的问题也可能与此有关。 如果要保存您的文档,请确保您致电 next()

固定版本

user.pre("save", function(next) {
    if(!this.trial){
        //do your job here
    }
    next();
}

【讨论】:

  • 我们可以在这里现实一点吗?请注意,由于您的问题本身没有提到“预保存挂钩”,所以这并不是任何人都会想到的解决方案。是的,当然如果没有调用中间件延续,那么代码只会卡住而不继续。这些实际上是“回调”而不是承诺。
  • 感谢您挽救了我的理智...同样的事情发生了,我浪费了大约 3 个小时试图弄清楚 WTH 正在发生...
【解决方案3】:

这听起来很疯狂。我已经尝试解决这个问题好几个小时了。看了这么多堆栈溢出帖子。。难以置信。

你知道那是什么吗?我没有在 url 的末尾指定数据库。

所以不是

"mongodb://127.0.0.1:27017/test"

我有

"mongodb://127.0.0.1:27017

我为此浪费了一整天。我真的希望我得到某种错误。保存记录总是返回正常。在数据库日志中,我连接正常。但我真的需要看看细节。是的,它连接到 mongo 实例,但没有连接到数据库本身。啊!

【讨论】:

  • 哦,伙计,你在 2020 年挽救了生命:D 谢谢,我也犯了同样的错误,忘记添加数据库名称。
  • 在我的情况下,问题是 ,我像这样在 中留下了 。我是多么愚蠢。大声笑
【解决方案4】:

就像保罗说的。很可能您在“req.user”对象上调用保存,该对象不是 Mongoose 对象。确保你正在做这样的事情:

//I am using your 'user' schema
var userModel = mongoose.model('User', user);
var User = mongoose.model('User');
var newUser = new User(req.user);
newUser.save(function(error, user){
   //your code
}

【讨论】:

  • 不,这不起作用,我确定 .save() 有问题
【解决方案5】:

以防万一其他人发生这种情况。

另一个原因可能是您的 mongodb 实例没有打开的连接。检查您的输出以获取适当的连接反馈。

[initandlisten] 接受来自 127.0.0.1:40448 #1 的连接(现在打开 1 个连接)

【讨论】:

  • 耶稣,谢谢你.. 卡在这上面 20 分钟
【解决方案6】:

我遇到了同样的问题,结果instance.save() 返回了一个承诺。所以你需要做的就是处理承诺。 使用async/await-

await instance.save()

【讨论】:

    【解决方案7】:

    对于任何与我有相同错误的人.. 如果您在很短的时间内调用 .save() 两次。最后一次调用将被丢弃。 我的问题是这个。

    //module usersave(userData)
    {
      await userData.save()
    }
    //module A
    {...todos
      moduleB(userData)
      ...some todos that doesn't take much time.
      await usersave(userData) //second call
    }
    //module B(userData)
    {
     ...todos;
     await usersave(userData) // first call
    }
    

    => Object.save() 在模块 B 中被调用,并在模块 A 中立即再次调用。(无论您创建保存模块还是直接调用 Object.save() 都没有关系)。 这些类型的调用堆栈不会发出错误,并且两个模块都正常返回成功。但是,由于在 mongodb 实际反映更改之前调用了第二个调用,因此稍后的调用将被丢弃。 问题是它返回就好像它们实际上已保存一样,因此您无法捕获错误。

    解决方案:只需等待。 await new Promise(r=>setTimeout(r,2000)) 会做。

    【讨论】:

      猜你喜欢
      • 2021-02-10
      • 1970-01-01
      • 2017-03-28
      • 2021-07-14
      • 2018-07-22
      • 1970-01-01
      • 2020-09-03
      • 2018-05-02
      • 2017-05-26
      相关资源
      最近更新 更多