7


下面是我试图保存到 MongoDB 的对象文字。它在作为 Express 服务器的 app.js 文件中定义。由于该对象是在服务器中硬编码的,我的假设是每次我运行服务器时都会将一个新副本保存到数据库中,或者至少该文档将保存一次,并在检测到该文件时被覆盖或保持不变新文档与上次服务器运行时保存的文档相同。令我惊讶的是,不仅没有在 MongoDB 中创建副本,而且根本没有保存文档。但是,已经创建了“新闻”集合,并通过 mongo shell 的“显示集合”进行了验证。此外,我在回调函数中没有收到任何错误。我还在我的 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'));
});

谢谢你的时间
最好的问候
贾里德

4

3 回答 3

25

看起来问题出在您的新闻模式的保存中间件中。

newsSchema.pre('save', function(next){
    if( !this.addedOn ) this.addedOn = new Date();
    if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
});

您的函数会收到一个“下一个”回调,您必须执行该回调才能让 mongoose 知道您已完成并准备好保存文档。既然你没有调用它,它可以解释为什么你什么都没有保存,也没有错误。

尝试像这样调用下一个:

newsSchema.pre('save', function(next){
    if( !this.addedOn ) this.addedOn = new Date();
    if( !this.addedBy ) this.addedBy = {first: "admin", last: "admin"};
    next();
});
于 2013-08-15T17:02:06.083 回答
5

尝试在本地重现此问题时,我发现了一些问题。

您没有在 newsSchema.pre('save') 中调用 next()

应该

newsSchema.pre('save', function(next){
    if( !this.addedOn ) this.addedOn = new Date();
    if( !this.addedBy ) this.addedBy = adminUser;
    next();
});

在执行任何这些操作之前,您还需要确保您已连接到数据库,不确定您是否连接到数据库,因为我没有看到那部分代码。

于 2013-08-15T17:02:20.643 回答
0

我的代码不同,但我的结果显然是一样的:显然,尽管调用了 .save,我并没有保存到 Mongo。但是,保存实际上正在发生,我只是没有意识到某些 Mongoose 参数的含义,并且它需要一些自由来形成您的集合名称。

更具体地说,当您使用时:

mongoose.model('MyModelName', invitationSchema);

为了形成您的集合名称,您的模型名称将转换为小写,并附加一个“s”(如果不存在)。另请参阅http://samwize.com/2014/03/07/what-mongoose-never-explain-to-you-on-case-sentivity/

如果需要,您可以在创建模式时使用集合名称参数在某种程度上绕过这些集合命名约定。请参阅http://mongoosejs.com/docs/guide.html#collection

这是我的:

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 });
于 2016-06-11T22:06:30.127 回答