我有一个像这样的视频模式:
const VideoSchema = new mongoose.Schema({
caption: {
type: String,
trim: true,
maxlength: 512,
required: true,
},
owner: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
// some more fields
comments: [{
type: mongoose.Schema.ObjectId,
ref: 'Comment',
}],
commentsCount: {
type: Number,
required: true,
default: 0,
},
}, { timestamps: true });
和一个简单的Comment模式:
const CommentSchema = new mongoose.Schema({
text: {
type: String,
required: true,
maxLength: 512,
},
owner: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
videoId: {
type: mongoose.Schema.ObjectId,
ref: 'Video',
required: true,
index: true,
},
}, { timestamps: true });
并使用这样的架构,我可以对我的视频收藏集执行任何类型的查找查询,并在其中添加评论:
Video.find({ owner: someUserId }).populate({ path: 'comments' });
我的问题是,在视频收藏夹中保留评论ID的必要性是什么?鉴于我已经在我的Comment模式中为videoId字段建立了索引,摆脱这些注释ID及其计数并使用聚合$ lookup来查找视频的注释将是多么糟糕(就性能而言):>
Video.aggregate([
{
$match: {
owner: someUserId,
},
},
{
$lookup: {
from: 'comments',
localField: '_id',
foreignField: 'videoId',
as: 'comments',
}
}
])
这些在性能方面有何不同?
答案 0 :(得分:0)
$lookup
不可能比在实际视频对象上具有评论ID的列表更快。我的意思是,您必须对whole other request
做mongo才能立即获得它们。因此,从性能角度来看,显然查找会增加时间。假设您没有使用mongoose populate
将这些注释ID“转换”为引用的对象。
如果您要从视频中删除评论(以及实际计数道具),然后执行查找。由于您要立即在arg中进行匹配,然后执行简单的lookup
,所以我看不出这对您来说是一个瓶颈。您还可以优化/更改/调整聚合视图explain等。
您的视频架构将非常干净:
const VideoSchema = new mongoose.Schema({
caption: {
type: String,
trim: true,
maxlength: 512,
required: true,
},
owner: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
// some more fields
}, { timestamps: true });