用mongodb来写blog,Nodejs中文章和comments的保存问题
用mongodb来写blog,Nodejs中文章和comments的保存问题
文章放在一个collection,comments是放在文章这个collection里面好,还是另外建立一个collection来放好?
mongodb新手。
用mongodb来写blog,Nodejs中文章和comments的保存问题
背景
在构建博客系统时,通常会遇到如何存储文章和评论的问题。在MongoDB中,有两种主要的方式来组织这些数据:一种是将评论嵌入到文章文档中,另一种是将评论作为一个单独的集合来管理。
嵌入式 vs 引用式
-
嵌入式:
- 将评论直接嵌入到文章文档中。
- 示例结构:
{ "title": "My First Blog Post", "content": "This is the content of my first blog post.", "comments": [ { "author": "John Doe", "text": "Great post!", "createdAt": ISODate("2023-09-10T12:00:00Z") }, { "author": "Jane Smith", "text": "Thanks for sharing!", "createdAt": ISODate("2023-09-11T14:30:00Z") } ] }
-
引用式:
- 将评论存储在一个单独的集合中,并通过文章的
_id
来关联。 - 示例结构:
- 文章集合:
{ "_id": ObjectId("..."), "title": "My First Blog Post", "content": "This is the content of my first blog post." }
- 评论集合:
{ "postId": ObjectId("..."), "author": "John Doe", "text": "Great post!", "createdAt": ISODate("2023-09-10T12:00:00Z") }
- 文章集合:
- 将评论存储在一个单独的集合中,并通过文章的
选择哪种方式?
- 嵌入式适合于评论数量较少且不经常更新的情况。这样可以减少查询次数,提高性能。
- 引用式适合于评论数量较多且需要频繁更新的情况。这样可以更好地管理数据,避免单个文档过大。
示例代码
假设我们使用嵌入式的方式:
const mongoose = require('mongoose');
// 定义文章模型
const articleSchema = new mongoose.Schema({
title: String,
content: String,
comments: [{
author: String,
text: String,
createdAt: Date
}]
});
const Article = mongoose.model('Article', articleSchema);
// 创建一篇文章并添加评论
async function createArticleWithComments() {
const article = new Article({
title: 'My First Blog Post',
content: 'This is the content of my first blog post.'
});
article.comments.push({
author: 'John Doe',
text: 'Great post!',
createdAt: new Date()
});
await article.save();
}
createArticleWithComments().then(() => console.log('Article created with comments'));
总结
根据你的具体需求选择合适的方案。如果评论数量不多,嵌入式可能更简单高效;如果评论数量多且需要频繁操作,引用式可能更适合。
我补充一下:
我想到的做法是,在文章这个collection里面,加入一个array来存放所有comments,但是会不会因为comments数量比较多的时候,导致数据库性能下降。
如果下降的话,我想另外用一个comments的collection来存放,然后根据文章id来操作comments。
nodeclub的是分两个collection来设计的,comments根据文章id来操作。
在使用 MongoDB 存储 Blog 的文章和评论时,有两种常见的设计模式:嵌入式(Embedded)和引用式(Referenced)。每种方法都有其优缺点。
嵌入式设计
将评论嵌入到文章文档中。这种方式的优点是查询方便,不需要进行多次查询。缺点是当评论数量较多时,可能会导致文档过大,影响性能。
示例代码
const mongoose = require('mongoose');
const commentSchema = new mongoose.Schema({
author: String,
content: String,
createdAt: { type: Date, default: Date.now }
});
const postSchema = new mongoose.Schema({
title: String,
content: String,
comments: [commentSchema],
createdAt: { type: Date, default: Date.now }
});
const Post = mongoose.model('Post', postSchema);
// 创建一篇文章
async function createPost() {
const post = new Post({
title: 'My First Blog Post',
content: 'This is my first blog post.',
comments: [
{
author: 'Alice',
content: 'Great post!',
createdAt: new Date()
}
]
});
await post.save();
}
createPost();
引用式设计
将评论存储在一个单独的集合中,并通过文章的 _id
来引用。这种方式的优点是评论可以独立于文章进行扩展和管理。缺点是需要进行两次查询,一次获取文章,另一次获取评论。
示例代码
const mongoose = require('mongoose');
const commentSchema = new mongoose.Schema({
postId: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' },
author: String,
content: String,
createdAt: { type: Date, default: Date.now }
});
const Comment = mongoose.model('Comment', commentSchema);
// 创建一篇文章
async function createPost() {
const post = await new Post({
title: 'My First Blog Post',
content: 'This is my first blog post.'
}).save();
// 创建一条评论
const comment = await new Comment({
postId: post._id,
author: 'Alice',
content: 'Great post!',
createdAt: new Date()
}).save();
return post;
}
createPost();
总结
- 嵌入式:适用于评论数量较少且查询频率较高的场景。
- 引用式:适用于评论数量较多且需要独立管理的情况。
选择哪种方式取决于具体的应用场景和需求。