我正努力地使用Mongoose模型填充来引用来自两个MongoDB集合的数据。这两种模式如下:
// SCHEMA SETUP - Artist
var artistSchema = new mongoose.Schema({
name: String,
venuesPlayed: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "Venue"
}
}
});
var Artist = mongoose.model("Artist", artistSchema);
// SCHEMA SETUP - Venue
var venueSchema = new mongoose.Schema({
name: String,
address: String,
});
var Venue = mongoose.model("Venue", venueSchema);
我想做的是在showArtist.ejs(列出有关特定艺术家的详细信息)上,我希望用户能够从所有场所的下拉列表中进行选择,并选择该艺术家拥有的场所玩过。因此,我正在努力奋斗并且非常感谢提供帮助的两点是:
谢谢!
答案 0 :(得分:0)
关于第一点,您的架构基本上是正确的,但是,如果您想在艺术家架构中存储多个场所引用,则可能要使用一个列表:
var artistSchema = new mongoose.Schema({
name: String,
venuesPlayed: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Venue"
}]
});
这将允许您通过引用venuesPlayed[index]
来检索每个场所的ObjectId,除非您要存储其他属性,否则无需分配其他键。
第二点,您可以使用populate()
方法在检索时将ObjectId替换为引用的文档:
let artist = await Artist.findOne(some_query).populate({ 'venuesPlayed' });
在这种情况下,some_query
将是JSON query
,以唯一地标识特定艺术家。如果留为空白,Mongoose只会返回它在数据库中找到的第一个艺术家文档。另外,如果您保留了ObjectId作为引用,则可以使用findById()
。
在没有populate()
方法(例如Mongoose <3.2)的情况下,您可以选择使用$lookup
聚合,或在单独的查询中手动迭代场所ObjectId。
如果要在服务器端执行此查询(通常是这样),则仍然需要在客户端发送此数据。使用Express,您可以通过creating a route并使用res.send()
来实现,或者更可能是res.render()
。您可以在提供的链接中找到完整的API参考,但是一条简单的(静态)路由可能看起来像这样:
app.get('/showSomeArtist', function(req, res) {
let artist = await Artist.findOne({ name: 'Some Artist' }).populate({ 'venuesPlayed' });
res.render('showArtist', { artist });
}
然后,您可以从EJS文件访问artist
对象。您需要详细说明上述示例,以更改要渲染的艺术家。我建议将路由参数作为一种潜在的解决方案(在Express文档中)。