[英]optimize mongo query to get max date in a very short time
我正在使用下面的查询来获取名为 KPI 的集合中的最大日期(名为 extractDate 的字段),因为我只对字段 extractDate 感兴趣:
@Override
public Mono<DBObject> getLastExtractionDate(MatchOperation matchOperation,ProjectionOperation projectionOperation) {
return Mono.from(mongoTemplate.aggregate(
newAggregation(
matchOperation,
projectionOperation,
group().max(EXTRACTION_DATE).as("result"),
project().andExclude("_id")
),
"kpi",
DBObject.class
));
}
正如您在上面看到的,我需要首先使用匹配操作(matchOperation)过滤结果,然后我正在执行投影操作以仅提取字段“extractionDate”的最大值并将其重命名为结果。
但是这个查询花费了很多时间(有时超过20秒),因为我有大量的数据,我已经在字段extractionDate上添加了一个索引但是我没有得到很多,所以我正在寻找一种方法来尽可能快地桅杆。
更新:
我们在集合中拥有的文档数量kpi :4280 万份文档
正在执行的查询:
Streaming aggregation: [{ "$match" : { "type" : { "$in" : ["INACTIVE_SITE", "DEVICE_NOT_BILLED", "NOT_REPLYING_POLLING", "MISSING_KEY_TECH_INFO", "MISSING_SITE", "ACTIVE_CIRCUITS_INACTIVE_RESOURCES", "INCONSISTENT_STATUS_VALUES"]}}}, { "$project" : { "extractionDate" : 1, "_id" : 0}}, { "$group" : { "_id" : null, "result" : { "$max" : "$extractionDate"}}}, { "$project" : { "_id" : 0}}] in collection kpi
索引调整将更多地取决于$match
表达式中的属性。 您应该能够在 mongosh 中运行查询并获得解释计划以确定您的查询是否正在扫描集合。
其他要考虑的事情是集合的大小与服务器的工作集。
也许用$match
表达式更新你的问题, explain plan
,也许还有当前的索引定义集,我们可以改进索引策略。
最后,“巨大”是相当主观的吗? 您是在查询数百万或数十亿的文档,平均文档大小是多少?
假设您只过滤一个字段并聚合一个字段,您会发现最好的结果是索引
{ "type":1,"extractionDate":1}
该索引应该涵盖您的查询 - 因为$in
将意味着将选择扫描,但对小索引的扫描明显优于对整个文档集合的扫描。
注意。 现有索引extractionDate_1_customer.irType_1
对此查询没有任何帮助。
由于以前使用这种方法的答案,我能够优化请求:
@Override
public Mono<DBObject> getLastExtractionDate(MatchOperation matchOperation,ProjectionOperation projectionOperation) {
return Mono.from(mongoTemplate.aggregate(
newAggregation(
matchOperation,
sort(Sort.Direction.DESC,EXTRACTION_DATE),
limit(1),
projectionOperation
),
"kpi",
DBObject.class
));
}
此外,我必须在 extractDate 和类型(我在 matchOperation 中的字段)上创建一个复合索引,如下所示:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.