mongodb - 为聚合查询调整 AWS DocumentDB(MongoDB 兼容)集合的最佳策略是什么

标签 mongodb performance aws-documentdb

我在 DocumentDB 集群中有一个集合(观察)。该集合最近被清除,但文档中的文件通常超过 200GB。以下是文档示例。

示例文档

{
    "_id" : ObjectId("5edfe9eb8b9b6d37ffc2b9ec"),
    "deviceId" : "5e86371746e0fb0001cbbf9b",
    "data" : {
        "type" : "HUMIDITY",
        "reading" : 20.1,
        "units" : "rh"
    },
    "timestamp" : ISODate("2020-06-10T05:00:00.000Z")
}

性能不佳的查询是:

db.observation.aggregate([
            {
                "$match": {
                    "deviceId": req.params.deviceId, 
                    "timestamp": {
                        $gte: new Date(req.params.timestamp), $lt: new Date()
                    }
                }
            }, { 
                "$group": {
                    "_id": {
                        "$add": [
                            { "$subtract": [
                                { "$subtract": [ "$timestamp", new Date(0) ] },
                                { "$mod": [ { "$subtract": [ "$timestamp", new Date(0) ] }, 1000 * 60 * aggMins ]}
                            ] },
                            new Date(0)
                        ]
                    }, 
                    "timestamp" : { "$first": "$timestamp" },
                    "units" : { "$first": "$data.units" },
                    "avg": { 
                        "$avg": "$data.reading" 
                    },
                }
            }, {
                "$project": {
                    "_id": 0,
                    "timestamp": 1,
                    "avg": 1,
                    "units": 1
                }
            }
        ])

在查询结果中运行 explain():

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "observation",
        "winningPlan" : {
            "stage" : "HASH_AGGREGATE",
            "inputStage" : {
                "stage" : "IXSCAN",
                "indexName" : "deviceId_1",
                "direction" : "forward"
            }
        }
    },
    "executionStats" : {
        "executionSuccess" : true,
        "executionTimeMillis" : "13092.126",
        "planningTimeMillis" : "8.470",
        "executionStages" : {
            "stage" : "HASH_AGGREGATE",
            "nReturned" : "1",
            "executionTimeMillisEstimate" : "13083.523",
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : "240266",
                "executionTimeMillisEstimate" : "12915.796",
                "indexName" : "deviceId_1",
                "direction" : "forward"
            }
        }
    },
    "ok" : 1
}

我正在寻求有关如何优化上述查询的建议。

最佳答案

我不是 DocumentDB 方面的专家,但这里有一些想法。你需要一个一个地尝试它们,看看什么对你最有帮助:

  1. 在第一阶段,match,使用project参数传递你只需要的字段。

  2. 不要在同一个调用中获取单元,只获取时间戳。这样做的原因是您在 match 中使用了时间戳,因此您手边已经有了它。但是,获取单位对于 DocumentDB 来说变得更加困难——这是我的理解,我在这里可能是错误的。在经典的 MongoDB 中,最好在一次调用中获取所有内容,但在 DocumentDB 中,数据分布不同。

最后,上面的评论之一建议创建一个 TTL 索引。这绝对不是最好的方法:TTL 索引需要对 DocumentDB 进行大量 IO 操作,而且这些操作非常昂贵。 AWS 建议删除集合并创建一个新集合,而不是使文档过期。

请记住,与大型集合相比,DocumentDB 在小型集合中的表现要好得多。因此,这里最好的方法可能是每设备周收集一次;类似 metrics_device1_20200701 的索引完全适合内存。

关于mongodb - 为聚合查询调整 AWS DocumentDB(MongoDB 兼容)集合的最佳策略是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63001571/

相关文章:

python - pandas read_table vs. read_csv vs. from_csv vs. read_excel 的性能差异?

Android 预加载 Recycleview 内容

mongodb - AWS文档数据库在查找查询中不使用elemMatch运算符中的索引?

java - 运行集成测试时嵌入 MongoDB

c# - 提取列表的 k 个最大元素

aws-documentdb - mongodb索引什么时候加载到内存中?

mongodb - 从 AWS Glue 连接到 DocumentDB

ruby-on-rails - 在 Ruby on Rails 中的 MongoDB 中搜索两个条件

mongodb - 我可以在无服务器模式下使用 MongoDb 吗?

java - MongoDB:IllegalStateException:Spring Boot 应用程序中的池已关闭错误消息