从多个 Mongoose 模型返回数据

Returning data from multiple Mongoose models

大家好,我正在努力寻找将 mongoose 与 node 和 express 结合使用的最佳方法。用户登录后,我想获取分布在多个 collections/mongoose 模型中的用户的所有数据。这是我开始的一个例子,我得到了特定用户的所有 类:

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;

基本上,我在我的用户 table 中有一个名为 'group' 的密钥,它是一组与我的组 table 中的特定文档相关的密钥。我想 return 所有类型为 '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});
    }
});

首先,我会将我的模型彼此分开,并且只在该文件中定义与这些模型相关的函数。我还会通过回调使函数 return 响应。如果没有,后面的函数可能会在数据库查询完成之前执行。在您的代码示例中, 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 */ });
        });
    });
});

好的,这还算粗略。但这就是你如何在没有承诺的情况下做到这一点。关键是要确保您不会在前一个函数执行之前执行下一个函数,并保持您的模型独立,以便您的代码更易于管理。

我希望这是有道理的。