【问题标题】:Mongoose schema field definition issue (keywords: nodejs, req.body, extend, field, type)Mongoose 模式字段定义问题(关键字:nodejs、req.body、extend、field、type)
【发布时间】:2015-09-09 11:25:23
【问题描述】:

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


我有一个模式,它的定义如下:

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

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

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 添加了一条记录(文档)。但它不包含用户字段,如下所示:

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

太奇怪了!!!用户字段在哪里???


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


起初我创建了一个解决方案如下:

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

那么,问题出在哪里?

【问题讨论】:

    标签: node.js express mongoose extend


    【解决方案1】:

    您可以在 Mongoose 中设置subdocument schema

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

    【讨论】:

      【解决方案2】:

      我发现有一种Mongoose:Schema.Types.Mixed。因此:

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

      【讨论】:

        【解决方案3】:

        最终我发现问题是,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、nickname、contact的对象。


        所以最终的解决方案是:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-11
          • 2015-04-03
          • 1970-01-01
          • 2017-11-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多