繁体   English   中英

优化 mongo 查询以在很短的时间内获得最大日期

[英]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

解释计划: 在此处输入图像描述

集合 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM