猫鼬模型人口

时间:2019-01-28 00:03:26

标签: node.js mongodb mongoose

我正努力地使用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. 在“艺术家模式”下引用场地模式的方式正确吗?
  2. 在showArtist.ejs页面上,如何在下拉列表(例如html select标签或类似的内容)列表中引用场地?尤其是这一点,我尝试遇到的所有问题都遇到了一个错误,即“未定义的场地”。

谢谢!

1 个答案:

答案 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文档中)。