我有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' }
问题是:如何填充填充字段的子字段(帐户)([articles])?我现在就是这样做的:
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: Populate a populated field但没有找到真正的解决方案
答案 0 :(得分:57)
首先,更新mongoose 3到4&然后使用最简单的方法在猫鼬中进行深度人口统计,如下所示:
假设您有Blog架构,其userId为ref Id&然后在用户中,您有一些评论作为架构审查的参考ID。所以基本上,你有三个架构: 1.博客 2.用户 3.审核
并且,您必须从博客查询,哪个用户拥有此博客&用户评论。 因此,您可以将结果查询为:
<BlogModel>.find({}).populate({path : 'userId', populate : {path : 'reviewId'}}).exec(function (err, res) {
})
答案 1 :(得分:28)
跨多个级别填充
假设您有一个跟踪用户朋友的用户架构。
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' }
});
答案 2 :(得分:20)
Mongoose现在有一个新方法Model.populate
用于深层关联:
https://github.com/Automattic/mongoose/issues/1377#issuecomment-15911192
答案 3 :(得分:17)
可能有点太晚了,但是我写了一个Mongoose plugin来执行任意嵌套级别的深度填充。注册此插件后,您只需一行即可填写类别的文章和帐户:
Category.deepPopulate(categories, 'articles.account', cb)
您还可以指定populate options来控制每个填充路径的limit
,select
...等内容。查看插件文档以获取更多信息。
答案 4 :(得分:8)
在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);
});
});
答案 5 :(得分:6)
或者您可以通过以下方式将Object传递给populate方法:
const myFilterObj = {};
const populateObj = {
path: "parentFileds",
populate: {
path: "childFileds",
select: "childFiledsToSelect"
},
select: "parentFiledsToSelect"
};
Model.find(myFilterObj)
.populate(populateObj).exec((err, data) => console.log(data) );
答案 6 :(得分:3)
很抱歉破坏了你的泡沫,但是没有直接支持的解决方案。至于Github issue #601,它看起来很严峻。根据{{3}},看起来开发人员承认这个问题对手动递归/深度人口感到满意。
因此,从发行说明中,推荐的方法是在回调中嵌套填充的调用,因此在exec()
函数中,使用categories.populate
在发送响应之前进一步填充。
答案 7 :(得分:2)
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提出的问题,并填充了许多关系的两个层次。首先获取user
,填充其相关order
的数组并包含每个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
中使用。
答案 8 :(得分:0)
这个概念是深层人口。 这里的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)
}
});
答案 9 :(得分:0)
如果要选择内部填充,则应尝试以下方式:
我有预订模式:
AAA
和体验模式:
let Booking = new Schema({
..., // others field of collection
experience: { type: Schema.Types.ObjectId, ref: 'Experience' },
...},{
collection: 'booking'
});
找到预订时,获得体验的体验类型和位置:
let Experience = new Schema({
...,
experienceType: {type: Schema.Types.ObjectId, ref: 'ExperienceType'},
location: {type: Schema.Types.ObjectId, ref: 'Location'},
...} // others field of collection
,{
collection: 'experience'
});