mongodb - 性能聚合 MongoDB 匹配和示例
问题描述
我有一个包含 700 万条记录的集合。我需要在特定日期范围内选择 X 个随机元素。
这是我的架构
mongoose.Schema({
transactionId: {type: String, required: [true, 'transactionId is required'], index: true},
createdAt: {type: Date, required: [true, 'date is required'], index: true},
userId: {type: String, required: [true, 'userId is required']}
});
这是我正在做的查询
TransactionModel.aggregate([
{
$match: {
createdAt: {$gte: startDate, $lt: endDate}
}
},
{
$sample: {
size: 100,
}
}
]
这些是我的结果:
Took 458ms to select 100 winners in date range: 1-5-2018 - 1-6-2018
Took 1524ms to select 100 winners in date range: 1-5-2018 - 1-9-2018
Took 2052ms to select 100 winners in date range: 1-4-2018 - 1-4-2019
Took 19249ms to select 100 winners in date range: 1-1-2018 - 1-1-2033
19 秒似乎相对较长,当我从聚合函数中删除 $match 时,只需 142 毫秒即可从 700 万条记录中选出 100 个获胜者。
有没有办法可以通过 match 子句提高速度?
解决方案
正如 Anthony Winzlet 已经写过的,您需要在 createdAt 字段上建立一个索引。这可以是单个字段索引或复合索引,其中 createdAt 是第一部分。
除此之外,您应该考虑有一个 $project 阶段,以防不需要文档的所有字段。
理想情况下,您有复合索引,它涵盖了您的查询。
您可以使用 explain() 来查看发生了什么:
collection.find(
{createdAt: {$gte: startDate, $lt: endDate}},
{ created: 1, otherField: 1 }
).explain('executionStats')
推荐阅读
- sql - 使用 GROUP BY 和 CASE pr IF 或 IF EXIST 过滤
- amazon-web-services - 新的 MTURK SDK:设置沙盒端点?
- jenkins - Jenkins 不一致(文件每次都更改)
- continuous-integration - Gitlab-runner Virtualbox执行器不会上传工件
- python - Python分组和计算
- node.js - 欧洲的 Stripe Connect:使用支付意图向客户收费(React 和 Node js)
- ruby-on-rails - rails console OR irb 找出当前环境的 RAILS_VERSION
- r - 如何使用 dplyr 根据原始列中的字符将一列变成 3?
- html - RTSP 链接无法在 Google Chrome 中打开
- c++ - QT:QTimeEdit 小部件中“向上”和“向下”箭头的事件