2017-10-19 4 views
2

私はmongoose populateクエリオプションを試していますが、なぜクエリオプションが機能しないのかわかりません。Async Waterfallでクエリオプションを設定する

私は、ユーザーのスキーマがあります。

async.waterfall([ 
    function(callback) { 
    User 
     .findOne({ 'username': username }) 
     .exec((err, result) => { 
     if (result) { 
      callback(null, result); 
     } else { 
      callback(err); 
     } 
     }); 
    }, 

    function(userid, callback) { 

    // find user's feed 
    Feed 
     .find({}) 
     // .populate('user', {_id: userid._id}) <== this one also doesn't work 
     .populate({ 
     path: 'user', 
     match: { '_id': { $in: userid._id } } 
     }) 
     .exec(callback); 
    } 
], function(err, docs) { 
    if (err) { 
    return next(err); 
    } 

    console.log(docs); 
}); 
:私は次のコードのような async waterfallを使用し、私はすべての feed userによってIDを見つけたい

const mongoose = require('mongoose'); 
const Schema = mongoose.Schema; 

const FeedSchema = new Schema(
    { 
    user: { type: Schema.ObjectId, ref: 'User' }, 
    notes: { type: String, required: true }, 
    trx_date: { type: Date }, 
    status: { type: Boolean, Default: true } 
    }, 
    { timestamps: true } 
); 

FeedSchema.set('toObject', { getters: true }); 

module.exports = mongoose.model('Feed', FeedSchema); 

const mongoose = require('mongoose'); 
const Schema = mongoose.Schema; 

const UserSchema = new Schema(
    { 
    username: { type: String, required: true }, 
    email: { type: String }, 
    name: { type: String }, 
    address: { type: String } 
    }, 
    { timestamps: true } 
); 
module.exports = mongoose.model('User', UserSchema); 

とフィードスキーマを

上記のコードでは、私はすべてのフィードを手に入れました。クエリオプションは全く機能しません。間違っていましたか?

助けていただければ幸いです。

答えて

2

_idの値が、まだ入力されている「前」の"user"プロパティに既に格納されているものである場合に、「アフター」集団に一致すると思われる理由がわかりません。 .findOne()は、文書全体を返していることを当然の心の中

async.waterfall([ 
    (callback) => 
    User.findOne({ 'username': username }).exec(callback), 

    (user, callback) => { 
    if (!user) callback(new Error('not found')); // throw here if not found 
    // find user's feed 
    Feed 
     .find({ user: user._id }) 
     .populate('user') 
     .exec(callback); 
    } 
], function(err, docs) { 
    if (err) { 
    return next(err); 
    } 

    console.log(docs); 
}); 

キーピング、あなただけの新しい内_idプロパティをしたいので:それは代わりに.find()に本当に単純な「クエリ」状態だ。このよう

クエリ。また、最初のウォーターフォール機能での「ジャグリング」は必要ないことにも注意してください。エラーがあれば、それはエンドコールバックに「速く失敗する」、そうでない場合には結果を通過するでしょう。代わりに次のメソッドに「見つからない」というデリート。もちろん

この"Promises"がしばらくの周りされていると、あなたが実際にそれらを使用しなければならないので、本当に必要はありません。

User.findOne({ "username": username }) 
.then(user => Feed.find({ "user": user._id }).populate('user')) 
.then(feeds => /* do something */) 
.catch(err => /* do something with any error */) 

または実際にあなたのMongoDBがそれをサポートしているところ$lookupを使用して:

User.aggregate([ 
    { "$match": { "username": username } }, 
    { "$lookup": { 
    "from": Feed.collection.name, 
    "localField": "_id", 
    "foreignField": "user", 
    "as": "feeds" 
    }} 
]).then(user => /* User with feeds in array /*) 

これは出力が少し違っていますが、実際に少し変更して同じように見えるように変更することもできますが、これは一般的な考え方になります。

重要なのは、複数の要求を発行するのではなくサーバーが結合を実行するようにすることが一般的には重要です。

+0

ありがとうございました。あなたが言ったようにPromisesを使用するように私のコードを変更しました。 – metaphor

関連する問題