Mongodb 聚合管道优化 - $match 的 2 阶段
Posted
技术标签:
【中文标题】Mongodb 聚合管道优化 - $match 的 2 阶段【英文标题】:Mongodb aggregation pipeline optimization - 2 stage of $match 【发布时间】:2019-06-10 15:00:28 【问题描述】:我最近在研究聚合管道的性能优化。在决定要索引哪个时,我遇到了这个问题。我为 'receiverId': 1,'type': 1
设置了一个复合索引。
我原来的管道是这样的。我正在考虑是否索引isRead
也是必要的。我之所以没有创建三字段复合索引是因为其他查询只使用了recieverId
和type
。
notifications.aggregate([
$match:
'recieverId': ObjectId(xxx),
'type': xxx,
'isRead': false
,
...
,
], (err, result) =>
return res.status(200).json(result);
);
所以,我在下面改了这个。想知道这样的管道在过滤recieverId
和type
后是否可以节省一些计算成本。 isRead
, 第二个 $match
是否会从第一个 $match
的结果中过滤?
notifications.aggregate([
$match:
'recieverId': ObjectId(xxx),
'type': xxx,
,
$match:
'isRead': false
,
...
,
], (err, result) =>
return res.status(200).json(result);
);
【问题讨论】:
【参考方案1】:实际上,您如何编写并不重要,因为 mongo 会优化此管道。
来自文档:
当一个 $match 紧跟另一个 $match 之后,这两个阶段可以合并为一个 $match。
阅读有关它和其他管道优化 mongo 所做的here。
【讨论】:
感谢链接,我读到了,我还在工作室 3T 中进行了管道测试,但仍在考虑是否创建包含isRead
字段的复合索引,因为每当用户使用时,该值都会改变阅读。对上述查询有何建议?
将isRead
字段添加到您的索引将有助于mongo,因为它不需要过滤它。这意味着它将有助于运行时。需要考虑的一件事(这对大多数人来说不是问题)是索引大小,在这种情况下应该不会有太大的不同。
感谢,最后一个问题,例如,我总共有5个查询,前4个只查询recieverId
和type
字段,只有最后一个查询三个字段recieverId
, type
& `isRead',一个复合索引(3个字段)是否足以支持所有5个查询?
是(取决于索引构建顺序),例如索引x, y, z
可以支持对x
、x,y
和x,y,z
的查询。也阅读了这个here。以上是关于Mongodb 聚合管道优化 - $match 的 2 阶段的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB $geoNear 聚合管道(使用查询选项和使用 $match 管道操作)给出不同的结果
MongoDb 聚合 $match 错误:“参数必须是聚合管道运算符”