从多个Mongoose模型返回数据

时间:2016-10-18 13:04:29

标签: node.js mongodb express mongoose mongoose-schema

嘿伙计,所以我试图找到使用mongoose with node和express的最佳方法。一旦用户登录,我想获取分布在多个集合/猫鼬模型中的用户的所有数据。这是我开始的一个例子,我得到了特定用户的所有类:

var userSchema = new Schema({
    firstName: String,
    lastName: String,
    email: {type: String, required: true, unique: true},
    school: String,
    teacher: Boolean,
    admin: Boolean,
    moderator: Boolean,
    birthday: Date
});

userSchema.getClasses = function (userId) {
    User.find({_id: userId}, function (err, user) {
        Groups.find({
            _id: { $in: [user.groups]},
            type: "class"
        }, function(err, data){
            console.log(data);
            return(data);
        });
    });
}

var User = mongoose.model('User', userSchema);

module.exports = User;

基本上我的用户表中有一个名为'group'的密钥,它是一个与我的groups表中的特定文档有关的密钥数组。我想返回类型为“class”的所有组。

我对整个过程的另一个担忧是我想使用不同的函数获取不同的数据,这可能会给我带来异步问题。这是我的路线,所以你可以看到我想要实现的目标。我添加了作业作为例子。

router.get('/', function(req, res) {
    //user not logged in
    if(!req.session.user){
        res.redirect('/login');
    }else{
        //get groups
        var classes = User.getClasses(req.session.user._id);
        //get assignments
        var assignments = ExampleModel.getAssignments(req.session.user._id);
        console.log(req.session.user.firstName);
        res.render('home/index.jade', {classes: classes, assignments: assignments});
    }
});

1 个答案:

答案 0 :(得分:0)

首先,我将模型彼此分开,只定义与该文件中的那些模型有关的功能。我还让这些函数通过回调返回它们的响应。如果没有,后面的函数可能会在数据库查询完成之前执行。在您的代码示例中,res.render可以(并且可能将)在填充类和赋值之前执行。

将用户模型(在./models/user.js中)更改为以下内容:

var mongoose = require('mongoose');

var UserSchema = mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true
    },
    other fields here...
});

var User = module.exports = mongoose.model('User', UserSchema);

然后,对于每个函数,定义如下:

module.exports.getUserByEmail = function(email, callback){
    User.findOne({email: email }, callback);
}

这只是一个例子,但您可能会使用类似的东西来获取用户在登录功能期间。

然后在路径文件中,您将导入用户模型(以及您需要使用的其他模型,例如组),如下所示(./routes/users.js):

var express = require('express');
var router = express.Router();
var User = require('../models/user');
var Group = require('../models/group');

(假设您在路线文件夹和模型文件夹中的模型中有路线。)

然后,在您的路线中,您可以按如下方式获取所需的数据:

router.get('/', function(req,res) {
    var email = req.user.email; // If you store it there.
    User.getUserByEmail(email, function(err, user) {
        if (err) throw err;
        // Check for an error
        // Now do something with the user object.
        console.log(user._id);
        Group.getUserGroups(user._id, function(err,groups) {
            if (err) throw err;
            // now you have some groups
            res.render('views/file.jade',{ /* vars */ });
        });
    });
});
好的,所以这很粗糙。但是,没有Promise,你就是这样做的。关键是要确保在上一个函数执行之前不执行下一个函数,并保持模型分离,以便您的代码更易于管理。

我希望这是有道理的。