Mongoose模式字段定义问题(关键字:nodejs,req.body,extend,field,type)

我花了半个小时才弄清楚是什么问题,所以我需要发表这个问题来节省你的宝贵时间。


我有一个架构,其定义如下:

var mongoose = require('mongoose'); var ItemSchema = new mongoose.Schema({ title: String, desc: String, price: Number, owner: { // this field would be filled with req.session.user uid: {type: Number, index: true}, nickname: String, contact: String } }); module.exports = mongoose.model('ItemSchema', ItemSchema); 

然后,如果前端发送如下请求:

 console.log( req.body ); /* { title: 'apple', desc: 'nice apple', price: 100 } */ 

我的Express路由器代码写成:

 ... req.body.owner = req.session.user; var newItem = new ItemSchema( req.body ); newItem.save(function(err, re) { if (err) throw err; res.json(re); }); 

之后,我的ItemSchema添加了一个logging(文档)。 但它不包含用户字段,如下所示:

 > db.item.findOne(); { _id: ObjectId('xxxxxxxxxxxxxxxxxxxxxxxx'), title: 'apple', desc: 'nice apple', price: 100 } 

真奇怪! 用户字段在哪里?


我必须强调,如果console.log(req.body),它确实包含用户字段。


起初我创build了一个解决scheme如下:

 req.body.user = { uid: req.session.user.uid, nickname: req.session.user.nickname, contact: req.session.user.contact }; // It works, but looks stupid 

然后我用下划线:

 var newItem = new ItemSchema( _.extend(req.body, {user: req.session.user}) ); // It doesn't work, I don't know why 

最后,我发现它一定是Mongoose Schema Definition的问题,于是我试着:

 var ItemSchema = new mongoose.Schema({ title: String, desc: String, price: Number, owner: {type: { // here is the key!!! uid: {type: Number, index: true}, nickname: String, contact: String }} }); 

从那时起,没有更多的问题,我可以编码:

 req.body.user = req.session.user; // ok 

但是我发现我之前的定义应该是正确的,如http://mongoosejs.com/docs/guide.html所介绍的那样:

 var mongoose = require('mongoose'); var Schema = mongoose.Schema; var blogSchema = new Schema({ title: String, author: String, body: String, comments: [{ body: String, date: Date }], date: { type: Date, default: Date.now }, hidden: Boolean, meta: { // here, same data structure with my user field votes: Number, favs: Number } }); 

那么,这是什么问题?

你可以在Mongoose中设置一个子文档模式

 var UserSchema = new mongoose.Schema({ uid: {type: Number, index: true}, nickname: String, contact: String }, {_id: false}) var ItemSchema = new mongoose.Schema({ title: String, desc: String, price: Number, owner: UserSchema }); 

我发现有一种types的Mongoose:Schema.Types.Mixed。 从而:

 ... user: {type: Schema.Types.Mixed}, // ok, but no index set ... 

最终,我意识到问题是,请求。用户不是一个普通的对象,让我们看看它是如何发生的:

 // UserSchema.js ... UserSchema.statics.getSessionFields = function(uid, cb) { this.findById(uid).select('uid nickname contact').exec(cb); }; ... // app.js ... app.use(function(req, res, next) { var UserDB = require('path/to/UserSchema.js'); UserDB.getSessionFields(12345, function(err, re) { req.session.user = re; // here is the problem next(); }); }); ... 

这是一个查询对象 ,而不是对象只是包含uid,昵称,联系人。


所以最终的解决scheme是:

 UserDB.getSessionFields(12345, function(err, re) { req.session.user = re.toJSON(); // just the way as Backbone next(); });