问题描述
DocumentDB 忽略任何字段的索引而不是排序
db.requests.aggregate([
{ $match: {'deviceid': '5f68c9c1-73c1-e5cb-7a0b-90be2f80a332'}},{ $sort: { 'Timestamp': 1 } }
])
有用信息:
> explain('executionStats')
{
"queryPlanner" : {
"plannerVersion" : 1,"namespace" : "admin_portal.requests","winningPlan" : {
"stage" : "IXSCAN","indexName" : "Timestamp_1","direction" : "forward"
}
},"executionStats" : {
"executionSuccess" : true,"executionTimeMillis" : "398883.755","planningTimeMillis" : "0.274","executionStages" : {
"stage" : "IXSCAN","nReturned" : "20438","executionTimeMillisEstimate" : "398879.028","serverInfo" : {
...
},"ok" : 1.0,"operationTime" : Timestamp(1622585939,1)
}
> db.requests.getIndexKeys()
[
{
"_id" : 1
},{
"Timestamp" : 1
},{
"deviceid" : 1
}
]
当我在不排序的情况下查询文档或使用 find 和 sort 函数而不是聚合时,它工作正常。
重要说明: 它也适用于原始 MongoDB 实例,但不适用于 DocumentDB
解决方法
这更多是“DocumentDB 如何选择查询计划”一类的问题。 有很多关于 Mongo 如何在 stackoverflow 上does 的答案。
很明显,基于数据分布的失败试验可能会选择“错误”的索引,这里的问题是 DocumentDB 添加了 unknown layer。
Amazon DocumentDB 在专门构建的数据库引擎上模拟 MongoDB 4.0 API,该引擎利用分布式、容错、自我修复的存储系统。因此,Amazon DocumentDB 和 MongoDB 之间的查询计划和 explain() 可能会有所不同。想要控制查询计划的客户可以使用 $hint 运算符来强制选择首选索引。
他们声称由于这一层差异可能会发生。
现在我们明白了为什么选择了错误的索引(有点)。我们能做些什么?除非您想以某种方式删除或重建索引,否则您需要为管道使用 hint 选项。
db.collection.aggregate(pipeline,{hint: "index_name"})