猫鼬实例 .save() 不工作

Posted

技术标签:

【中文标题】猫鼬实例 .save() 不工作【英文标题】:Mongoose instance .save() not working 【发布时间】: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");
)

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


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

【问题讨论】:

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

    Schema.pre("保存") 将数据保存到 dabe 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)) 会做。

【讨论】:

以上是关于猫鼬实例 .save() 不工作的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS - .save() 不是一个函数。无法通过猫鼬创建集合

collection.save() 在 mongodb 中无法正常工作

Mongoose .save() 不能在没有回调的情况下工作

猫鼬 document.populate() 不工作

猫鼬 findOneAndUpdate 和 runValidators 不工作

猫鼬 findOneAndUpdate 和 runValidators 不工作