问题
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:
- Blog object contains an array of
Category
objects (refs) to be able to get all the categories this blog is related to. - 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