首页 > 解决方案 > 猫鼬模型种群

问题描述

我正在努力使用 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 (其中列出了有关特定艺术家的详细信息)上,我希望用户能够从所有场地的下拉列表中进行选择,并选择艺术家曾演奏过的场地。因此,我正在努力解决并非常感谢您的帮助的两点是:

  1. 我在 Artist Schema 下引用 Venue 模式的方式是否正确?
  2. 在 showArtist.ejs 页面上,如何在下拉列表(例如 html 选择标签或类似内容)列表中引用场地?尤其是这一点,我遇到了困难,因为我尝试过的所有事情都遇到了错误,“未定义的场地”。

谢谢!

标签: node.jsmongodbmongoose

解决方案


对于您的第一点,您的架构大多是正确的,但是如果您想在您的艺术家架构中存储多个场地引用,您可能希望使用一个列表来代替:

var artistSchema = new mongoose.Schema({
    name: String,
    venuesPlayed: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "Venue"     
    }]
});

这将允许您通过引用检索每个场所的 ObjectId,venuesPlayed[index]除非您想存储其他属性,否则无需分配额外的键。

对于第二点,您可以使用该populate()方法将 ObjectIds 替换为检索时引用的文档:

let artist = await Artist.findOne(some_query).populate({ 'venuesPlayed' });

在这种情况下,some_query将是JSON query唯一标识特定艺术家的。如果留空,Mongoose 将简单地返回它在数据库中找到的第一个艺术家文档。或者,findById()如果您保留了 ObjectId 作为参考,则可以使用。

如果没有该populate()方法(例如 Mongoose < 3.2),您的替代方法是使用$lookup聚合,或在单独的查询中手动迭代场地 ObjectIds。

如果您在服务器端执行此查询(通常是这种情况),您仍然需要在客户端发送此数据。使用Express,您可以通过创建路线并使用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 });
}

artist然后您可以从您的 EJS 文件中访问该对象。您需要详细说明上面的示例以更改渲染的艺术家。我建议将路由参数作为一种潜在的解决方案(在 Express 文档中)。


推荐阅读