0

背景: ユーザーが投票投票を投稿できるアプリ。
User モデルの Polls モデルへの参照を設定するのに少し問題があります。私は mongoose.populate を使用して、世論調査にデータを入力しようとしています。私のルートでは、populate 関数が正しく機能していません (返されたユーザーは null です)。これが私のモデルです...

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

           });        
     });

ヘルプ、アドバイス、アイデアをいただければ幸いです。ありがとう。

4

2 に答える 2

1

送信したコードでは、明示的にUser.

やりたいことを処理するには 2 つの方法があります。一方が他方より優れているので、その理由を説明します。

次のように、Poll の配列を 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 ( 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'}
});

繰り返しますが、mongoose.Schema 宣言でnewを使用する必要があることに注意してください。

このアプローチを採用する場合、作成時に poll オブジェクトに user._id を追加するだけで済みます。

その後、必要に応じて、Poll を取得するときに User を取得できます。

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 オブジェクトとして作成した投票の配列。

2 番目の方法は、ドキュメントの肥大化を回避するという 1 つの理由で優れている可能性があります。以前の回答についてコメントしたり、格下げしたりするほどの評判はないようですが、深刻な点でそれは正しくありません。 mongoose が populate 呼び出しを解決するために、ユーザー スキーマにポーリングの配列と、ポーリング スキーマにユーザー (作成者) を含める必要は絶対にありません。

境界のないモデル スキーマによって参照される配列がある場合は常に (ユーザーは好きなだけポーリングを作成できます)、データベース内の各ユーザー ドキュメントの大規模なシステムが巨大になるリスクがあります...すべてのポーリングでユーザーが作成し、Polls コレクションに新しい Poll ドキュメントを追加し、かつ親の User ドキュメントのサイズを増やしています。

基本的に同じ情報を2回保存しています..どのデータベースでも悪い習慣です。

親オブジェクトが持つことができる子の数に制限されている場合、たとえば、ユーザーがプログラムで 3 つのポーリングの作成に制限されている場合、配列を User モデルに追加しても問題ありません。

ただし、ユーザーが必要な数の投票を作成できるなど、子の成長に強制的な制限がない場合は、 User スキーマに投票の配列を持たず、代わりに投票にクリエーターを配置することをお勧めします。作成ユーザーを参照するスキーマ。

どちらの場合でも、両方ではなくどちらか一方を実行します...どちらの場合でも、関係を 2 つの異なるドキュメントに保存せずに関係のデータを取得する効果的な方法があります。

于 2016-10-04T03:58:45.583 に答える
1

マングースの人口は非常に優れた機能です。私があなたのコードで見たものから、プールをユーザーに割り当てていないようです。ユーザー内のプールを参照する最初の部分はありますが、プール内のユーザーを参照する2番目の部分はなく、マングースは操作を実行するために両方を必要とします。

プールには名前とオプションのリストが必要だと思います。コードで確認できるのは、プールの配列を含むプールであるため、説明に合わせてプール スキーマを変更しました。

この新しいプール スキーマを使用して、プール内のユーザーへの参照を追加してみてください。

プール.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 に答える