Mongoose – how to limit depth of populate() level?

半世苍凉 提交于 2019-12-11 12:59:14

问题


I have two schemas:

var categorySchema = mongoose.Schema({
    title: String,
    blogs: [{ type: ObjectId, ref: 'Blog' }]
})

var blogSchema = mongoose.Schema({
    title: String,
    description: String,
    category: [{ type: ObjectId, ref: 'Category' }],
    created: {type: Number, default: new Date().getTime()}
})

var Category = mongoose.model('Category', categorySchema)
var Blog = mongoose.model('Blog', blogSchema)

They are cross-referring:

  1. Blog object contains an array of Category objects (refs) to be able to get all the categories this blog is related to.
  2. Category object contains an array of Blog objects (refs) to be able to get all the blogs of this category.

The problem is when I try to get a certain Blog. I need to populate category array to get it's titles:

Blog
    .findOne({_id: _._id})
    .populate('category')
    .exec(function (err, __) {
        callback(err, __);
    })

I get...

{ title: 'My Blog',
  description: 'description',,
  _id: 51cb6bd845ba145e02000001,
  __v: 0,
  created: 1372285906662,
  category: 
   [ { __v: 0,
       _id: 51cb5ed6fd63867905000002,
       priority: 3,
       title: 'Music',
       blogs: [Object] } ],
}

Yep, I get categories titles, but I also get some objects in blogs – they were also populated. But Blog-objects may contain a lot of subobjects (posts) and as we remember category field. So, all the objects in category field will be populated recursively and as I have cross links between Blog and Category it will be populating in a loop?

How to limit population level? I dont want Blog/category[n]/blogs: [] to be populated, only direct category fields, such as title. Thanks.


回答1:


From the mongoose docs:

It is debatable that we really want two sets of pointers as they may get out of sync. Instead we could skip populating and directly find() the stories we are interested in.

I would remove the reference of blogs in the category schema and just query for the documents that you are interested.

"Blog object contains an array of Category objects (refs) to be able to get all the categories this blog is related to":

Blog.findOne({_id: blogId})
    .populate('category')
    .exec(function (err, blog) {
        callback(err, blog);
        //blog.category is the array you want
    })

"Category object contains an array of Blog objects (refs) to be able to get all the blogs of this category":

Blog.find({category: catId}) 
    .exec(function (err, blogs) {
        callback(err, blogs);                        
    })

This is a simplified syntax of the $all query that actually searches inside the array of categories for the specified id.



来源:https://stackoverflow.com/questions/17331682/mongoose-how-to-limit-depth-of-populate-level

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!