Node.js Mongoose模式字段定义问题(关键字:nodejs、req.body、extend、field、type)
我花了半个小时才弄明白是什么问题,所以我需要发布这个问题,以节省您宝贵的时间Node.js Mongoose模式字段定义问题(关键字:nodejs、req.body、extend、field、type),node.js,express,mongoose,extend,Node.js,Express,Mongoose,Extend,我花了半个小时才弄明白是什么问题,所以我需要发布这个问题,以节省您宝贵的时间 我有一个模式,它的定义如下: var mongoose = require('mongoose'); var ItemSchema = new mongoose.Schema({ title: String, desc: String, price: Number, owner: { // this field would be filled with req.session.us
我有一个模式,它的定义如下:
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
}
*/
> db.item.findOne();
{
_id: ObjectId('xxxxxxxxxxxxxxxxxxxxxxxx'),
title: 'apple',
desc: 'nice apple',
price: 100
}
req.body.user = {
uid: req.session.user.uid,
nickname: req.session.user.nickname,
contact: req.session.user.contact
}; // It works, but looks stupid
然后,如果前端发送post请求,如下所示:
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
}
*/
> db.item.findOne();
{
_id: ObjectId('xxxxxxxxxxxxxxxxxxxxxxxx'),
title: 'apple',
desc: 'nice apple',
price: 100
}
req.body.user = {
uid: req.session.user.uid,
nickname: req.session.user.nickname,
contact: req.session.user.contact
}; // It works, but looks stupid
我的快速路由器代码,写在:
...
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添加了一条记录(文档)。但它不包含用户字段,如下所示:
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
}
*/
> db.item.findOne();
{
_id: ObjectId('xxxxxxxxxxxxxxxxxxxxxxxx'),
title: 'apple',
desc: 'nice apple',
price: 100
}
req.body.user = {
uid: req.session.user.uid,
nickname: req.session.user.nickname,
contact: req.session.user.contact
}; // It works, but looks stupid
太奇怪了!!!用户字段在哪里
我必须强调,如果console.log(req.body)包含用户字段
首先,我创建了一个解决方案,如下所示:
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
}
*/
> db.item.findOne();
{
_id: ObjectId('xxxxxxxxxxxxxxxxxxxxxxxx'),
title: 'apple',
desc: 'nice apple',
price: 100
}
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
最后,我发现这一定是猫鼬模式定义的问题,所以我尝试:
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
但我发现我之前的定义应该是正确的,如下所述:
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
}
});
那么,问题出在哪里呢?我发现有一种猫鼬:Schema.Types.Mixed。因此:
...
user: {type: Schema.Types.Mixed}, // ok, but no index set
...
你可以在猫鼬身上建立一个
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
});
最终,我意识到问题是,req.session.user不是一个普通的对象,让我们看看它是如何产生的:
// 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();
});
});
...
此re是一个查询对象,而不是仅包含uid、昵称、联系人的对象
因此,最终的解决方案是:
UserDB.getSessionFields(12345, function(err, re) {
req.session.user = re.toJSON(); // just the way as Backbone
next();
});