J'ai le modèle Category
:
Category:
...
articles: [{type:ObjectId, ref:'Article'}]
Le modèle d'article contient la référence à Account model
.
Article:
...
account: {type:ObjectId, ref:'Account'}
Ainsi, avec le modèle de la catégorie articles
peuplée sera:
{ //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' }
La question est: comment peupler un sous-champ (compte) d'un champ rempli ([articles])? Voici comment je le fais maintenant:
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
Je sais que cela a été discuté ici: Mongoose: peupler un champ peuplé mais aucune solution réelle n'a été trouvée
Mongoose a maintenant une nouvelle méthode Model.populate
pour les associations profondes:
https://github.com/LearnBoost/mongoose/issues/1377#issuecomment-15911112
Tout d’abord, mettez à jour Mangouste 3 à 4 puis utilisez le moyen le plus simple pour la population profonde de Mangouste, comme indiqué ci-dessous:
Supposons que vous ayez un schéma de blog dont l'ID utilisateur est l'ID de référence puis, dans Utilisateur, une révision en tant qu'ID de référence pour la révision du schéma. Donc, fondamentalement, vous avez trois schémas: 1. Blog 2. Utilisateur 3. La revue
Et, vous devez interroger à partir d'un blog, quel utilisateur est propriétaire de ce blog et de l'avis de l'utilisateur . Vous pouvez donc interroger votre résultat comme suit:
<BlogModel>.find({}).populate({path : 'userId', populate : {path : 'reviewId'}}).exec(function (err, res) {
})
Remplir à plusieurs niveaux
Supposons que vous ayez un schéma d'utilisateur qui garde une trace des amis de l'utilisateur.
var userSchema = new Schema({
name: String,
friends: [{ type: ObjectId, ref: 'User' }]
});
Remplir vous permet d'obtenir la liste des amis d'un utilisateur, mais que se passe-t-il si vous souhaitez également que ses amis soient amis? Spécifiez l'option populate pour indiquer à mangouste de renseigner le tableau d'amis de tous les amis de l'utilisateur:
User.findOne({ name: 'Val' }).populate({
path: 'friends',
// Get friends of friends - populate the 'friends' array for every friend
populate: { path: 'friends' }
});
Référence: http://mongoosejs.com/docs/populate.html#deep-populate
C'est peut-être un peu trop tard, mais j'ai écrit un plug-in Mongoose pour effectuer une population profonde à n'importe quel niveau imbriqué arbitraire. Avec ce plugin enregistré, vous pouvez renseigner les articles et les comptes de la catégorie avec une seule ligne:
Category.deepPopulate(categories, 'articles.account', cb)
Vous pouvez également spécifier options de remplissage pour contrôler des éléments tels que limit
, select
... pour chaque chemin d'accès renseigné. Consultez la documentation du plugin pour plus d'informations.
Le moyen le plus simple de réaliser cela en 3.6 consiste à utiliser 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);
});
});
Désolé de faire éclater votre bulle, mais il n'y a pas de solution directement prise en charge pour cela. En ce qui concerne Le numéro de Github n ° 601 , il semble sombre. Selon les notes de version de 3.6 , il semble que les développeurs ont reconnu que le problème était satisfait de la population récursive/profonde manuelle.
Ainsi, dans les notes de publication, la méthode recommandée consiste à imbriquer des appels remplis dans le rappel. Par conséquent, dans votre fonction exec()
, utilisez categories.populate
pour remplir davantage avant d'envoyer une réponse.
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);
});
});
L'exemple suivant est inspiré de la question posée @codephobia et renseigne deux niveaux de nombreuses relations. Commencez par chercher une user
, remplissez son tableau de order
s connexes et incluez chaque 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[]
});
});
Cela fonctionne bien dans 3.8.8
mais devrait fonctionner dans 3.6.x
.
Ce concept est profond Population . Ici Calendrier, Abonnement, Utilisateur, Appartement sont des modèles ODM mangouste à différents niveaux
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)
}
});