我有3 Mongoose 收集:董事会,线程和答复。每个答复属于1线程(作为一个数组的项目在“答复”属性),每个线程属于1董事会(作为一个数组的项目在“线程”属性)。
正如下面的代码,每当我想通过发送帖子请求向数据库添加一个新的回复时,我必须更新所有3个集合:Board,Thread和Reply。
有没有其他的方法来实现这一点,而不必手动修改每个集合一个接一个?
app.route('/api/replies/:board').post(async (req, res) => {
const { text, delete_password, thread_id } = req.body;
const board = req.params.board;
if (!thread_id.match(/^[0-9a-fA-F]{24}$/)) {
res.send('Thread ID is invalid');
} else {
const updateBoard = await BoardModel.findOne({name: board}).exec(); //find the Board in Board collection
const updateThread = updateBoard.threads.id(thread_id); //find the Thread in that Board
const updateThreadDB = await ThreadModel.findById(thread_id).exec(); //find the Thread in Thread collection
if (!updateThreadDB || !updateBoard) {
res.send("Board or thread not found");
} else {
//Add new Reply
const newReply = new ReplyModel({
text: text,
delete_password: delete_password,
reported: false,
})
let saveReply = await newReply.save(); //save Reply to Reply collection
//Update Thread and Board
updateThreadDB.replies.push(saveReply);
updateThread.replies.push(saveReply);
let saveBoard = await updateBoard.save(); //update new Board collection
let saveThread = await updateThreadDB.save(); //update new Thread collection
res.json(saveReply);
}
}
})
字符串
这是我的模型文件:
const mongoose = require('mongoose');
mongoose.connect(process.env.DB);
const { Schema } = mongoose;
const replySchema = new Schema ({
text: {type: String, required: true},
created_on: {type : Date, required: true, default: () => { return new Date() }},
delete_password: {type: String, required: true},
reported: {type: Boolean, required: true},
})
const Reply = mongoose.model('Reply', replySchema);
const threadSchema = new Schema ({
text: {type: String, required: true},
created_on: {type : Date, required: true, default: () => { return new Date() }},
bumped_on: {type : Date, required: true, default: () => { return new Date() }},
reported: {type: Boolean, required: true},
delete_password: {type: String, required: true},
replies: {type: [replySchema], required: true},
});
const Thread = mongoose.model('Thread', threadSchema);
const boardSchema = new Schema ({
name: {type: String, required: true},
threads: {type: [threadSchema], required: true},
});
const Board = mongoose.model('Board', boardSchema);
exports.Board = Board;
exports.Thread = Thread;
exports.Reply = Reply;
型
1条答案
按热度按时间368yc8dk1#
看看你的模式和你存储数据的方式,你似乎在复制数据。例如,你在
replies
集合中创建了一个新的Reply
:字符串
然后,您将相同的数据添加两次。一次添加到
threads
集合中的threds.replies
数组,然后一次添加到boards
集合中的boards.threads
数组:型
Mogodb文档的大小限制为16MB,因此如果您的应用程序很受欢迎,您最终可能会超过每个
boards
文档的大小,将所有这些threads
和嵌套的replies
存储在单个文档中。您需要使用两个东西,referenced documents和Model.findByIdAndUpdate()。
你可以像这样更新你的模式:
型
现在,当您创建
Thread
时,您只需要将Thread
的_id
(即ObjectId
)推入Board.threads
一次。然后,当您创建
Reply
时,您只需将Reply
的_id
(即ObjectId
)推入Thread.replies
一次。下面是一个如何为Board创建新Thread的示例:
型
现在,您不需要再次触摸
Board
文档,直到您需要删除Thread
。以下是如何创建回复的示例:
型
请注意,我不需要去获取
Board
父文档。现在您可以创建任意多个回复,只需将每个回复的_id
推送到父线程中。这将节省保存大量空间,因为只有ObjectId
存储在Thread
中,只有ObjectId
存储在每个Board
中。最后,如果你想获得每个引用的文档,你可以使用populate。请阅读它以了解,但这里是一个如何做到这一点的示例:
型