我有以下用于表示多对多关系的模式:
var CategorySchema = new Schema({
title: {type: String},
});
mongoose.model('Category', CategorySchema);
var ProductSchema = new Schema({
title: {type: String},
categories: [
{
type: Schema.ObjectId,
ref: 'Category'
}
]
});
mongoose.model('Product', ProductSchema );
当我查询类别或产品时,我希望能够在结果中获得所有链接的文档。
在查询产品时填充类别非常简单:
Product.find().populate('categories').exec(...)
但是如何从类别方面做到这一点?我知道我可以在CategorySchema中的Product文档中添加一个ObjectId引用数组。但是我想避免双向引用(我不想维护它,并且存在不一致的风险)。
编辑:这是我实施的解决方案
/**
* List all Categories
*/
exports.all = function (req, res) {
//Function needed in order to send the http response only once all
//the categories' product has been retrieved and added to the returned JSON document.
function sendResponse(categories) {
res.json(categories);
}
AppCategory.list(function (err, categories) {
if (err) {
errors.serverError();
} else {
_.forEach(categories, function (category, index) {
category.products = [];
Product.byCategory(category._id, function (err, products) {
category.products= category.products.concat(products);
if (index === categories.length - 1) {
sendResponse(categories);
}
});
});
}
});
};
ProductSchema.statics = {
byCategory: function (categoryId, callback) {
this.find({'categories': categoryId})
.sort('-title')
.exec(callback);
}
};
答案 0 :(得分:2)
你可能不想这样做。 :-)我猜一个产品可以在一些合理的少数类别中,但一个类别可能有数千种产品。在这种情况下,从效率的角度来看,尝试Category.populate('products')
不会起作用。您将使用大量内存,无法以简单的方式进行分页,在产品属于多个类别时将重复的产品数据加载到内存中等等。通过直接查询产品集合来更好地加载产品类别。您可以轻松地按类别过滤la Product.find({'categories._id': $in: arrayOfCategoryIds}})
。