猫鼬型号人口
我与猫鼬模型居民苦苦挣扎,从两个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(其中列出了有关特定艺术家的细节),我希望用户能够从所有场馆的下拉列表中选择,然后选择艺术家已经在发挥的场地。所以这两点,我挣扎,并与将不胜感激帮助是:
- 是我所引用的艺术家下的场地模式的方式模式是否正确?
- 在showArtist.ejs页面,如何引用场馆下拉(如HTML select标签或类似的东西)名单?正是这一点尤其是我与作为一切我已经试过我发现了一个错误,“场馆未定义”有困难。
谢谢!
回答如下:为了您的第一点,你的模式大多是正确的,但是如果你要存储的艺术家架构中的多个场地的引用,你可能想用一个列表,而不是:
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
唯一标识一个特定的艺术家。如果留空,猫鼬会返回它发现数据库中的第一位艺术家文档。另外,您也可以使用findById()
如果都保留了的ObjectId作为参考。
在不存在populate()
方法(例如猫鼬<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文档中)。