我目前正在学习如何在我的NodeJS项目中使用Mongoose模块来使用MongDB。
我有一个要求,我有一系列过山车和每个过山车有一些过山车评论,所以它像一对多的类型关系,每个个人过山车有很多过山车评论。
在了解创建Mongoose模式时,我将过山车ID添加到过山车评论模式中,以便创建的每个评论都通过ID链接到其过山车。
这是过山车模式:
/**
* Rollercoaster Schema
*/
var RollercoasterSchema = new Schema({
name: {
type: String,
default: '',
required: 'Please fill Rollercoaster name',
trim: true
},
created: {
type: Date,
default: Date.now
},
});
以下是Coaster Review架构:
/**
* Coasterreview Schema
*/
var CoasterreviewSchema = new Schema({
review: {
type: String,
default: '',
required: 'Please fill Coasterreview review',
trim: true
},
created: {
type: Date,
default: Date.now
},
rollercoaster: {
type: Schema.ObjectId,
ref: 'Rollercoaster'
}
});
当我获得过山车评论列表然后填充过山车时,这个架构工作正常。
然而,我还要求获得过山车的列表以及与每个过山车相关的过山车评论(如果有的话)。我对如何最好地做到这一点的知识有限,我目前的方法意味着我需要获得过山车的列表然后循环通过这个列表然后必须再次进入数据库,每个过山车取得每个过山车的过山车评论列表,这对我来说似乎不正确,这里是伪代码:
var mongoose = require('mongoose'),
Rollercoaster = mongoose.model('Rollercoaster'),
CoasterReview = mongoose.model('Coasterreview');
Rollercoaster.find().sort('-created').exec(function(err, rollercoasters) {
if (err) {
return 'Error';
} else {
//Need to loop through the RollerCoasters from the result
//In each loop need to use CoasterReview.find to get the coaster reviews for each roller coaster
//This will result in a lot of calls to the DB, there must be a better way to do this?
rollercoasters.forEach(function(coaster){
CoasterReview.find().sort('-created').exec(function(err, reviews) {
//Add the list of reviews to the rollercoaster here
//This is async code so how do I handle this correctly, this current manner doesn't seem to be the correct way
});
});
}
});
所以我的问题是我的方法对于我获得我的过山车评论列表是正确的,但是对于获得过山车档案文件列表及其相关的过山车评论文档似乎有点低效,任何人都可以帮助指出我的权利关于如何使用Mongoose做到最好的方向?
修改
使用Mi Ke Bu的代码让我更接近,这是代码:
Rollercoaster.find(query).sort('-created').populate('user', 'displayName').populate('themepark').exec(function(err, rollercoasters) {
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
//list of ids
var rcIds = rollercoasters.map(function(el){return el._id;});
//select all reviews with 'rollercoaster' = any _id from list
CoasterReview
.find({'rollercoaster':{$in:rcIds}}).sort('-created').exec(function(err, reviews) {
//res.jsonp(rollercoasters);
res.jsonp(reviews);
});
}
});
然而,这只是单独给了我过山车的列表和过山车评论列表,因为过山车和它的过山车评论之间没有任何联系,我将不得不在这里循环通过阵列尝试将过山车评测与每个过山车相匹配,有没有办法使用Mongoose避免这种情况并让它返回如下内容:
[
{
"_id": "55c2106227f2a878292a564d",
"__v": 0,
"created": "2015-08-05T13:32:18.473Z",
"name": "Jurassic Park : The Ride",
coasterreviews: [
{
"_id": "55dcbd9662a5516c39d27946",
"rollercoaster": "55c2106227f2a878292a564d",
"__v": 0,
"created": "2015-08-25T19:10:14.392Z",
"review": "The theming is fantastic"
},
{
"_id": "55d8bb292d03db3c1310d465",
"rollercoaster": "55c2106227f2a878292a564d",
"__v": 0,
"created": "2015-08-22T18:10:49.201Z",
"review": "Woah what a ride, really thrilling and a great experience."
}
]
},
{
"_id": "55c20f0f27f2a878292a564c",
"__v": 0,
"created": "2015-08-05T13:26:39.055Z",
"name": "Dragon Challenge : Hungarian Horntail",
coasterreviews: [
{
"_id": "55d8d21908eda5a018c22ed4",
"rollercoaster": "55c20f0f27f2a878292a564c",
"__v": 0,
"created": "2015-08-22T19:48:41.854Z",
"review": "Great ride"
}
]
},
]
答案 0 :(得分:1)
试试这个:
} else {
//list of ids
var rcIds = rollercoasters.map(function(el){return el._id;});
//select all reviews with 'rollercoaster' = any _id from list
CoasterReview
.find({"rollercoaster":{$in:rcIds}})
.sort(...)
.exec(function(err,reviews){
//upd start
reviews.forEach(function(r){
var c=rollercoaster.filter(function(el){return el._id.equals(r.rollercoaster);});
c.coasterreviews=c.coasterreviews || [];
c.coasterreviews.push(r);
});
res.jsonp(rollercoaster);
//upd end
});
}
关于$ in read:http://docs.mongodb.org/manual/reference/operator/query/in/