node.js - Mongoose:3 路文档连接

标签 node.js mongodb express mongoose mongoose-populate

我正在学习 Mongoose ,需要一些帮助。我有 3 个集合,在一次 API 调用中,我想创建 3 个相互引用的文档;下面的“加入”:

  • 用户 - 需要引用 chirps
  • 视频 - 需要引用 chirps
  • Chirps - 需要引用用户和 Chirps

问题:我知道我可以执行 model.create() 并在每个回调中传入新文档,然后更新到相应的文档,但我想知道是否有更简洁的方法?

抱歉,如果我不清楚这个问题。如果有什么不明白的地方请问我。

代码

var chirpSchema = new mongoose.Schema({
    date_created: { type: Date, default: Date.now }
  , content: { post : String }
  , _video: { type: $oid, ref: "video" }
  , _author: { type: $oid, ref: "user" }
});
var chirp = mongoose.model('chirp', chirpSchema);


var userSchema = new mongoose.Schema({
    date_joined: { type : Date, default: Date.now }
  , cookie_id: String,
  chirp_library: [{type: $oid, ref: "chirp"}]
})
var user = mongoose.model('user', userSchema);


var videoSchema = new mongoose.Schema({
    date_tagged: { type : Date, default: Date.now }
  , thumbnail_url : String
  , _chirps: [{type: $oid, ref: "chirp" }]
});
var video = mongoose.model('video', videoSchema);

最佳答案

Mongo 和其他 NoSQL 数据库不仅仅是 SQL 数据库的可互换替代品。它迫使您以不同的方式重新思考您的设计。这个概念并不是要定义一种关系。这个想法是在更少的查询中提供信息。在 Mongo 中,数组通常是需要避免的事情,特别是当它们有无限增长的潜力时。根据你的命名,这似乎很有可能。如果您保留其余架构并仅从用户和视频架构中删除这两个数组:

chirp.find({_author: yourUserId}).populate("_author") 为您提供与当前设计中的 user.findOne({_id: yourUserId}) 相同的信息。

同样,

chirp.find({_video: yourVideoId}).populate("_video")video.findOne({_id: yourVideoId})

唯一的问题是 .populate() 正在您拉动的每个 chirp 上运行。解决这个问题的方法是对 chirp 文档上的部分(或全部)作者和视频文档进行非规范化。我可能会如何设计它:

var chirpSchema = new mongoose.Schema({
    date_created: { type: Date, default: Date.now },
    content: { 
        post : String 
    },
    _author: { 
        _id: { type: $oid, ref: "video" },
        date_joined: { type: Date, default: Date.now }
    },
    _video: { 
        _id: { type: $oid, ref: "user" },
        date_tagged: { type: Date, default: Date.now },
        thumbnail_url: String
    }
});

var userSchema = new mongoose.Schema({
    date_joined: { type : Date, default: Date.now }
  , cookie_id: String
})

var videoSchema = new mongoose.Schema({
    date_tagged: { type : Date, default: Date.now }
  , thumbnail_url : String
});

重复数据是完全可以的,只要它能让你的查询更加高效。话虽这么说,你需要在阅读和写作之间取得平衡。如果您的用户信息或视频信息定期更改,则必须更新每个 chirp 文档上的数据。如果您的视频/作者中有一个定期更改的特定字段,并且在查询中不需要,您可以将该字段从 chirp 文档中删除。

关于node.js - Mongoose:3 路文档连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28361433/

相关文章:

node.js - Express 中间件中的 req.locals vs. res.locals vs. res.data vs. req.data vs. app.locals

node.js - Electron 在单独的线程上运行加密 Diffie Hellman key 生成

node.js - 更改mongo数据库

mongodb - 可以通过索引在 MongoDB 中使 $unwind 快速吗?

c# - 如何通过使用 MongoDB C# 驱动程序调用 obj.ToBsonDocument() 来全局忽略空值?

node.js - 在 Express 服务器上包含并自动编译 Sass

node.js - 执行错误 : Error: stdout maxBuffer exceeded if using child_process on Node js

node.js - 为什么我的所有图像都没有显示?

node.js - nodejs stream.Readable.push() 返回值的语义是什么

node.js - super 测试和类似路线的多次执行