猫鼬实例 .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 谢谢,我也犯了同样的错误,忘记添加数据库名称。 在我的情况下,问题是就像保罗说的。很可能您在“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() 不能在没有回调的情况下工作