麻烦 referencing/populating 另一个模型中的猫鼬模型

Trouble referencing/populating a mongoose model in another model

背景:允许用户post投票的应用程序。
我在用户模型中填充对我的投票模型的引用时遇到了一些麻烦。我正在使用 mongoose.populate 来尝试填充民意调查。在我的路线中,填充功能无法正常工作(返回的用户为空)。这是我的模型...

users.js:

// models/users.js

var mongoose = require('mongoose'),
    Poll = require('./poll');

//define the schema for our user model
var userSchema = mongoose.Schema({
    local:{
        email: String,
        password: String,
        name: String
    },
    twitter:{
        id: String,
        token: String,
        name: String
    },
    polls:[{type: mongoose.Schema.Types.ObjectId, ref:'Poll'}]
});

poll.js:

//load mongoose
var mongoose = require('mongoose'),
    User = require('./user');


var pollSchema = mongoose.Schema({
       name:String,
       options:[String],
       creator: {type:mongoose.Schema.Types.ObjectId, ref:'User'}
});


module.exports = mongoose.model('Poll', pollSchema);

这是我要实施人口的路线...

 //require user and poll model 
 var User = require('../models/user'),
 Poll = require('../models/poll');

 app.post('/dashboard', isLoggedIn, function(req,res){ 

    var poll = {name: req.body.name, 
                options: req.body.option, 
                creator: req.user.local.id};

    //create new poll 
    var newPoll = new Poll();
    newPoll.polls = poll;

    //find the user with the request id and populate polls reference in User (UserSchema)
    User.findById(req.user.local.id)
         .populate('polls')
          .exec(function(err,user){ // cant figure this out...

              if(err){return err;}

              console.log(user); // yields null

              res.send({success:true, message: "Post Successful!"});

           });        
     });

如有任何帮助、建议和想法,我们将不胜感激。谢谢

猫鼬中的种群是一个很棒的功能。从我在您的代码中看到的情况来看,您似乎没有为用户分配池。您有引用用户内部池的第一部分,但没有引用池内部用户的第二部分,猫鼬需要两者都执行操作。

我认为您希望池具有名称和选项列表。我在您的代码中看到的是一个包含池数组的池,因此我更改了池架构以适合您的解释。

尝试使用这个新的池架构在您的池中添加对用户的引用:

pools.js

var mongoose = require('mongoose');

var pollSchema = mongoose.Schema({
       name:String,
       options:[String],
       creator: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});


module.exports = mongoose.model('Poll', pollSchema);

现在,在保存池时,不要忘记添加您的用户参考。您正在为用户填充池,因此在 mongoose 回调中传递的对象将不是池列表,而是您要查找的用户。感谢 population,您将在属性 pools 中获得对象列表而不是 ID 列表。

 var User = require('../models/user'),
 Poll = require('../models/poll');

 app.post('/dashboard', isLoggedIn, function(req,res){ 

    var poll = {
       name: req.body.name, 
       options: req.body.option, 
       creator: req.user.local.id
     };

    var newPoll = new Poll();
    newPoll.polls = poll;

    User.findById(req.user.local.id)
         .populate('polls')
          .exec(function(err, user){
           /*
             You should get in user object something like:
             {
               local: {...},
               twitter: {...},
               pools: [{
                 name: 'Pool1',
                 options: [...]
               }]
              }
           */
           });        
     });
});

在您提交的代码中,您从未明确创建 User

有两种方法可以处理您想做的事情,一种比另一种更好,我会解释原因。

您可以像这样将投票数组添加到您的用户模型中:

var userSchema = new mongoose.Schema({
    local:{
        email: String,
        password: String,
        name: String
    },
    twitter:{
        id: String,
        token: String,
        name: String
    },
    polls:[{type: mongoose.Schema.Types.ObjectId, ref:'Poll'}]
});

请注意,您应该指定 userSchema = new mongoose.Schema.

如果这是您的选择,那么当您创建一个新的 Poll 实例时,您必须创建 Poll,检索适当的用户 (User.findById),然后将 Poll._id 推送到 user.polls,并保存用户。
这种方法将允许您在检索用户 object 时简单地调用 .populate('polls') 以获取结果集中所有用户的投票。

或者,您可以将 polls 数组保留在用户模型之外,而只需在您的 Poll 模式中创建引用:

var pollSchema = new mongoose.Schema({
       name:String,
       options:[String],
       creator: {type:mongoose.Schema.Types.ObjectId, ref:'User'}
});

再次注意,您应该在 mongoose.Schema 声明中使用 new

如果采用这种方法,您只需在创建投票时将 user._id 添加到投票 object 即可。

然后,如果您愿意,您可以在检索投票时检索用户:

Poll.findById(...however you are retrieving your Poll id...)
         .populate('creator')
          .exec(function(err, poll){....

如果您想列出给定用户发布的所有民意调查,只需按照以下行进行操作:

Poll.find({"creator": req.params.userId})
    .populate('creator')
    .exec(function(err, poll) {
        if(err) return err;
        res.json(poll);
    };

上面代码中的 req.params.userId 不应该被当成文字,这取决于你的应用程序如何检索用户 ID,同样响应 return 方法取决于你的特定应用程序,在上面的代码中,它是 returning 用户创建的民意调查数组 json object.

出于一个原因,第二种方法可能更好,它避免了文档膨胀。 我似乎没有足够的声誉来评论或降级以前的答案,但从一个严肃的角度来看,这是不正确的。 您绝对不必在用户架构中拥有投票数组,在猫鼬的投票架构中拥有用户(创建者)来解析填充调用。

任何时候你有一个由没有边界的模型架构引用的数组(用户可以创建任意数量的民意调查)你 运行 你的每个用户文档的大型系统的风险数据库变得庞大...对于用户创建的每个民意调查,您都在民意调查集合中添加一个新的民意调查文档,并且您正在增加 parent 用户文档的大小。

您实质上是将相同的信息存储了两次..对任何数据库都是不好的做法。

如果您的 parent object 被限制为它可以拥有的 children 的数量,假设用户在编程上被限制为创建 3 个民意调查,那么您可以添加数组到用户模型。

但是,如果 children 的增长没有强制限制,假设用户可以创建任意数量的民意调查,那么我建议您不要在 User 中设置民意调查数组模式,而是在 Poll 模式中有一个创建者引用创建用户。

在任何一种情况下,只做一个,而不是同时做...在任何一种情况下,都有一种有效的方法来获取关系的数据,而无需将关系存储在两个不同的文档中。