node.js Mongoose 不会将数据保存到 MongoDB
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18256707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mongoose doesn't save data to the MongoDB
提问by Jared Tomaszewski
Below is an object literal I am trying to save to MongoDB. It is defined within the app.js file which is an Express server. As the object is hardcoded within the server, my assumption was that a new copy would be saved to the DB every time I run the server, or at the very least the document would be saved once, and overridden or left unchanged upon detection that the new document is identical to the one saved on the last server run. To my astonishment, not only no copies are created within the MongoDB, but the document is not saved at all. However, the 'news' collection has been created, as verified with mongo shell 'show collections'. Also, I am not getting any error in the callback function. I also tried the Model.create(doc, fn) within my Express '/news' route, but this also doesn't work (the doc should be saved every time the '/news' route is called by the client, but it isn't). What am I missing?
Please, read my annotations marked with "<-" to see what other problems or unexpected behaviour I encounter. I will be very grateful if you could address those as well in your answer.
下面是我试图保存到 MongoDB 的对象文字。它在作为 Express 服务器的 app.js 文件中定义。由于对象是在服务器中硬编码的,我的假设是每次运行服务器时都会将一个新副本保存到数据库中,或者至少文档将保存一次,并在检测到新文档与上次服务器运行时保存的文档相同。令我惊讶的是,不仅在 MongoDB 中没有创建副本,而且根本没有保存文档。然而,'news' 集合已经创建,正如 mongo shell 'show collections' 所验证的那样。另外,我在回调函数中没有收到任何错误。我还在我的 Express '/news' 路线中尝试了 Model.create(doc, fn),但这也没有' t 工作(每次客户端调用“/news”路由时都应该保存文档,但事实并非如此)。我错过了什么?
请阅读我标有“<-”的注释,看看我遇到了哪些其他问题或意外行为。如果您能在回答中解决这些问题,我将不胜感激。
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, fs = require('fs');
// Defining connection to the database:
var mongoose = require('mongoose').
connect("mongodb://localhost:27017/my-test-db"),
db = mongoose.connection;
var Schema = mongoose.Schema;
var ObjectID = Schema.ObjectId;
// Setting up the debug flag:
mongoose.set('debug, true');
// Logging connection:
db
.on('error', console.error.bind(console, 'DB connection error.'))
.once('open', console.log.bind(console, 'DB Connection established.'));
// Defining MongoDB schemas:
var usr = new Schema({
first: String,
last: String
});
var newsSchema = new Schema({
headline: String,
bd: String,
imgURI: String,
imgThumbURI: String,
imgCaption: String,
addedOn: Date,
addedBy: {
type: ObjectID,
ref: 'usr'
}
// On user action 'save' populate the addedOn and addedBy fields before the news article is actually saved to the DB:
newsSchema.pre('save', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
});
// Indexing important fields:
usr.index({last: 1});
newsSchema.index({headline: 1});
//Adding the News model:
var News = mongoose.model('news', newsSchema);
var nws1 = new News({
headline: "Test news Headline",
bd: "Test news body. Test news body. Test news body. Test news body. Test news body. ",
imgURI: encodeURI("images/news/img.jpg"),
imgThumbURI: encodeURI("images/news/thumbs/img.jpg"),
imgCaption: "Test news image caption.",
addedOn: new Date(),
addedBy: {first: "Admin", last: "Admin"}
});
nws1.save(function(err, news){
if(err) return console.error("Error while saving data to MongoDB: " + err); // <- this gets executed when there's an error
console.error(news); // <- this never gets logged, even if there's no error.
});
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.resolve(__dirname + '/public'));
app.set('view engine', 'html')
.engine('html', function(path, options, fn){
if('finction' == typeof options){
fn = options, options = {};
}
fs.readFile(path, 'utf8', fn);
});
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session());
app.use(express.static(path.join(__dirname, 'public')));
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
Thank you for your time
Best regards
Jared
谢谢你的时间
最好的问候
贾里德
回答by supershabam
It looks like the problem is in your news schema's save middleware.
看起来问题出在您的新闻模式的保存中间件中。
newsSchema.pre('save', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
});
Your function receives a "next" callback which you must execute to let mongoose know that you are done and ready to save the document. Since you're not calling it, it could explain why you get nothing saved, and also no errors.
您的函数接收“下一个”回调,您必须执行该回调以让猫鼬知道您已完成并准备好保存文档。由于您没有调用它,它可以解释为什么您没有保存任何内容,也没有错误。
Try just calling next like this:
尝试像这样调用 next :
newsSchema.pre('save', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
next();
});
回答by Rik Leigh
I found a few problems when trying to reproduce this locally.
我在尝试在本地重现时发现了一些问题。
You're not calling next() in newsSchema.pre('save')
你不是在 newsSchema.pre('save') 中调用 next()
Should be
应该
newsSchema.pre('save', function(next){
if( !this.addedOn ) this.addedOn = new Date();
if( !this.addedBy ) this.addedBy = adminUser;
next();
});
You also need to make sure that you are connected to the db before doing any of this stuff, not sure if you are or not since i didn't see that part of the code.
在执行任何这些操作之前,您还需要确保您已连接到数据库,不确定您是否已连接,因为我没有看到那部分代码。
回答by Chris Prince
My code was different, but my result was apparently the same: Apparently, I wasn't saving to Mongo despite the .save call. HOWEVER, the save was actually taking place, I just didn't realize what some of the Mongoose parameters mean, and that it takes some liberties forming your collection name.
我的代码不同,但我的结果显然是一样的:显然,尽管调用了 .save ,我并没有保存到 Mongo。然而,保存实际上正在发生,我只是没有意识到一些猫鼬参数的含义,并且它需要一些自由来形成您的集合名称。
More specifically, when you use:
更具体地说,当您使用:
mongoose.model('MyModelName', invitationSchema);
to form your collection name, your model name gets converted to lower case and an "s" gets appended (if not there). See also http://samwize.com/2014/03/07/what-mongoose-never-explain-to-you-on-case-sentivity/
为了形成您的集合名称,您的模型名称将转换为小写并附加一个“s”(如果没有)。另见http://samwize.com/2014/03/07/what-mongoose-never-explain-to-you-on-case-sentivity/
You can, if you want, bypass these collection naming conventions to some extent by using a collection name parameter when you create the schema. See http://mongoosejs.com/docs/guide.html#collection
如果需要,您可以在创建架构时使用集合名称参数在一定程度上绕过这些集合命名约定。请参阅http://mongoosejs.com/docs/guide.html#collection
Here's mine:
这是我的:
const modelName = "SharingInvitation";
const collectionName = modelName + "s";
const numberOfHoursBeforeExpiry = 24;
var expiryDate = new Date ();
expiryDate.setHours(expiryDate.getHours() + numberOfHoursBeforeExpiry);
var invitationSchema = new Schema({
// _id: (ObjectId), // Uniquely identifies the invitation (autocreated by Mongo)
// gives time/day that the invitation will expire
expiry: { type: Date, default: expiryDate },
// The user is being invited to share the following:
owningUser: ObjectId, // The _id of a PSUserCredentials object.
capabilities: [String] // capability names
}, { collection: collectionName });

