这不是一个重复的问题。所有其他答案都表示解决方案是在排序键上创建索引。在我的情况下,我有一个索引,仍然面临这个错误
给出mongodb集合,文档类似于:
{
'_id': ...,
'title': ...,
'price': ...,
'category_id': ...,
'last_updated': ...,
... other keys
}
我在category_id
上有一个升序单字段索引,在last_updated
上有一个降序单字段索引。
以下查询崩溃:
> var c = db.collection_name.find({category_id: "categ_id"}, {_id: 0, price: 1, title: 1}).sort({last_updated: -1}).limit(20000).batchSize(500)
> c.forEach(function(doc) {
... ;
... })
2015-05-13T10:00:46.561+0000 E QUERY Error: error: {
"$err" : "getMore executor error: Overflow sort stage buffered data usage of 33554596 bytes exceeds internal limit of 33554432 bytes",
"code" : 17406
}
at Error (<anonymous>)
at DBQuery.next (src/mongo/shell/query.js:259:15)
at DBQuery.forEach (src/mongo/shell/query.js:414:20)
at (shell):1:3 at src/mongo/shell/query.js:259
以下是查询的解释,如果有帮助:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db_name.collection_name",
"indexFilterSet" : false,
"parsedQuery" : {
"category_id" : {
"$eq" : "categ_id"
}
},
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 0,
"price" : 1,
"title" : 1
},
"inputStage" : {
"stage" : "SORT",
"sortPattern" : {
"last_updated" : -1
},
"limitAmount" : 500,
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"category_id" : 1
},
"indexName" : "category_id_1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"category_id" : [
"[\"categ_id\", \"categ_id\"]"
]
}
}
}
}
}
},
"rejectedPlans" : [
{
"stage" : "LIMIT",
"limitAmount" : 500,
"inputStage" : {
"stage" : "PROJECTION",
"transformBy" : {
"_id" : 0,
"price" : 1,
"title" : 1
},
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"category_id" : {
"$eq" : "categ_id"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"last_updated" : 1
},
"indexName" : "last_updated_1",
"isMultiKey" : false,
"direction" : "backward",
"indexBounds" : {
"last_updated" : [
"[MaxKey, MinKey]"
]
}
}
}
}
}
]
},
"serverInfo" : {
"host" : "host",
"port" : 27017,
"version" : "3.0.2",
"gitVersion" : "6201872043ecbbc0a4cc169b5482dcf385fc464f"
},
"ok" : 1
}
有趣的是,此错误仅发生在特定类别而非全部。此外,如果我删除batchSize
选项,查询不会崩溃(无论我为批处理设置的大小)。
值得注意的是,last_updated
字段可能不存在于所有文档中。
答案 0 :(得分:3)
所以,结果是我的问题中的查询解释中的线索。由于在查询中使用了category_id
,查询优化器选择使用category_id
索引并完全忽略last_updated
索引。我的想法是它会使用category_id
来获取和last_updated
进行排序,但这似乎不是mongodb查询的工作方式。为了解决这个问题,需要按顺序为category_id
和last_updated
创建复合索引:
db.collection_name.createIndex({category_id: 1, last_updated: -1})