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(); });