0

背景:允许用户发布投票的应用程序。
我在 User 模型中填充对 Polls 模型的引用时遇到了一些麻烦。我正在使用 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'}]
});

投票.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!"});

           });        
     });

任何帮助、建议、想法将不胜感激。谢谢。

4

2 回答 2

1

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

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

尝试使用这个新的池模式添加对池中用户的引用:

池.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 回调中传递的对象将不是池列表,而是您要查找的用户。多亏了人口,您将在属性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: [...]
               }]
              }
           */
           });        
     });
});
于 2016-01-07T00:32:24.517 回答
1

在您提交的代码中,您永远不会显式创建User.

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

您可以向您的 User 模型添加一组 Polls,如下所示:

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 ( User.findById),然后将 Poll._id 推送到 user.polls,并保存 User。
这种方法将允许您.populate('polls')在检索用户对象时简单地调用它以获取结果集中的所有用户投票。

或者,您可以将 polls 数组排除在 User 模型之外,只需在 Poll 模式中创建引用:

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

再次注意您应该使用new与您的 mongoose.Schema 声明。

如果您采用这种方法,您只需在创建 poll 对象时添加 user._id 即可。

然后,如果您愿意,您可以在检索民意调查时检索用户:

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,同样,响应返回方法取决于您的特定应用程序,在上面的代码中它正在返回由用户创建为 json 对象的投票数组。

出于一个原因,第二种方法可能更好,它避免了文档膨胀。我似乎没有足够的声誉来评论或降级以前的答案,但在一个严重的方面它是不正确的。 您绝对不必在用户模式中拥有民意调查数组,并且在民意调查模式中拥有用户(创建者)以供 mongoose 解析填充调用。

每当您有一个由没有边界的模型架构引用的数组(用户可以创建任意数量的投票)时,您都会冒着风险,因为数据库中每个用户文档的大型系统变得庞大......对于每个投票用户创建,您正在 Polls 集合中添加一个新的 Poll 文档,并且您正在增加父 User 文档的大小。

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

如果您的父对象被限制为它可以拥有的子对象的数量,例如用户以编程方式限制为创建 3 个投票,那么您可以将数组添加到 User 模型中。

但是,如果对孩子的成长没有强制限制,比如用户可以根据需要创建任意数量的民意调查,那么我建议您在 User 模式中没有民意调查数组,而是在民意调查中有一个创建者引用创建用户的架构。

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

于 2016-10-04T03:58:45.583 回答