私はCategory
モデルを持っています:
Category:
...
articles: [{type:ObjectId, ref:'Article'}]
記事モデルにはAccount model
への参照が含まれています。
Article:
...
account: {type:ObjectId, ref:'Account'}
そのため、articles
が入力されたカテゴリモデルは次のようになります。
{ //category
articles: //this field is populated
[ { account: 52386c14fbb3e9ef28000001, // I want this field to be populated
date: Fri Sep 20 2013 00:00:00 GMT+0400 (MSK),
title: 'Article 1' } ],
title: 'Category 1' }
質問は次のとおりです。入力フィールド([記事])のサブフィールド(アカウント)を入力する方法は?ここに私が今それをする方法があります:
globals.models.Category
.find
issue : req.params.id
null
sort:
order: 1
.populate("articles") # this populates only article field, article.account is not populated
.exec (err, categories) ->
console.log categories
私はそれがここで議論されたことを知っています: マングース:移入されたフィールドに入力します が、実際の解決策は見つかりませんでした
Mongooseに新しいメソッドModel.populate
深い関連付けの場合:
https://github.com/Automattic/mongoose/issues/1377#issuecomment-15911192
まず、mongoose 3を4に更新し、次に以下のようにmongooseの深い人口に対して最も簡単な方法を使用します。
Ref IdとしてuserIdを持つBlogスキーマがあり、UserでスキーマReviewのref Idとしていくつかのレビューがあるとします。基本的に、3つのスキーマがあります。1.ブログ2.ユーザー3.レビュー
そして、あなたはブログからクエリする必要があります。どのユーザーがこのブログとユーザーレビューを所有しているか。したがって、次のように結果を照会できます。
BlogModel
.find({})
.populate({
path : 'userId',
populate : {
path : 'reviewId'
}
})
.exec(function (err, res) {
})
複数のレベルにまたがる
ユーザーの友達を追跡するユーザースキーマがあるとします。
var userSchema = new Schema({
name: String,
friends: [{ type: ObjectId, ref: 'User' }]
});
Populateを使用すると、ユーザーの友人のリストを取得できますが、ユーザーの友人の友人も必要な場合はどうでしょうか。 populateオプションを指定して、mongooseにすべてのユーザーの友人のfriends配列に入力するように指示します。
User.findOne({ name: 'Val' }).populate({
path: 'friends',
// Get friends of friends - populate the 'friends' array for every friend
populate: { path: 'friends' }
});
リファレンス: http://mongoosejs.com/docs/populate.html#deep-populate
少し遅すぎるかもしれませんが、ネストされた任意のレベルでディープポピュレーションを実行するために Mongooseプラグイン を作成しました。このプラグインを登録すると、1行だけでカテゴリの記事とアカウントを作成できます。
Category.deepPopulate(categories, 'articles.account', cb)
populate options を指定して、移入された各パスに対してlimit
、select
...などを制御することもできます。詳細については、プラグインのドキュメントをご覧ください。
3.6でこれを実現する最も簡単な方法は、Model.populate
。
User.findById(user.id).select('-salt -hashedPassword').populate('favorites.things').exec(function(err, user){
if ( err ) return res.json(400, err);
Thing.populate(user.favorites.things, {
path: 'creator'
, select: '-salt -hashedPassword'
}, function(err, things){
if ( err ) return res.json(400, err);
user.favorites.things = things;
res.send(user.favorites);
});
});
バブルを破裂させて申し訳ありませんが、これを直接サポートするソリューションはありません。 Github issue#601 に関しては、見苦しいようです。 .6リリースノート によると、開発者はこの問題が手動の再帰/ディープポピュレーションに満足していることを認めているようです。
そのため、リリースノートから推奨される方法は、コールバックにデータを設定した呼び出しをネストすることです。したがって、exec()
関数では、categories.populate
は、応答を送信する前にさらに入力します。
globals.models.Category.find()
.where('issue', req.params.id)
.sort('order')
.populate('articles')
.exec(function(err, categories) {
globals.models.Account.populate(categories, 'articles.account', function(err, deepResults){
// deepResult is populated with all three relations
console.log(deepResults[0].articles[0].account);
});
});
次の例は、@ codephobiaに尋ねられた質問に触発され、多くの関係の2つのレベルに入力します。最初にuser
をフェッチし、関連するorder
sの配列を作成して、各orderDetail
を含めます。
user.model.findOne()
.where('email', '***@****.com')
.populate('orders')
.exec(function(err, user) {
orderDetail.model.populate(user, 'orders.orderDetails', function(err, results){
// results -> user.orders[].orderDetails[]
});
});
これは3.8.8
で正常に動作しますが、3.6.x
で動作するはずです。
この概念は、深い人口です。ここで、Calendar、Subscription、User、Apartmentは、異なるレベルのマングースODMモデルです
Calendar.find({}).populate({
path: 'subscription_id',model: 'Subscription',
populate: {path: 'user_id',model: 'User',
populate: {path: 'apartment_id',model: 'Apartment',
populate: {path: 'caterer_nonveg_id',
model: 'Caterer'}}}}).exec(function(err,data){
if(!err){
console.log('data all',data)
}
else{
console.log('err err err',err)
}
});