我正在使用MongoDB 1.6.3来存储大集合(300k +记录)。我添加了一个综合索引。
db['collection_name'].getIndexes()
[
{
"name" : "_id_",
"ns" : "db_name.event_logs",
"key" : {
"_id" : 1
}
},
{
"key" : {
"updated_at.t" : -1,
"community_id" : 1
},
"ns" : "db_name.event_logs",
"background" : true,
"name" : "updated_at.t_-1_community_id_1"
}
]
但是,当我尝试运行此代码时:
db['collection_name']
.find({:community_id => 1})
.sort(['updated_at.t', -1])
.skip(@skip)
.limit(@limit)
我得到了:
Mongo :: OperationFailure(太多数据 对于没有索引的sort()。添加一个 索引或指定一个较小的限制)
我做错了什么?
答案 0 :(得分:14)
尝试添加{community_id: 1, 'updated_at.t': -1}
索引。它需要先按community_id
搜索,然后再排序。
答案 1 :(得分:4)
所以它“感觉”就像你正在使用索引,但索引实际上是一个复合索引。我不确定排序是否“足够聪明”才能使用部分索引。
所以有两个问题:
updated_at.t
听起来像是一个你可以进行范围查询的字段。如果范围查询是第二位,则索引可以更好地工作。community_id => 1
会有多少参赛作品回来?如果数字不大,你可以在没有索引的情况下进行排序。因此,您可能需要切换索引,并且可能必须更改排序以同时使用community_id
和updated_at.t
。我知道这似乎是多余的,但从那里开始,检查Google网上论坛是否仍无效。
答案 2 :(得分:2)
即使有索引,我认为如果你的结果集超过4MB,你仍然可以得到错误。
您可以通过进入mongodb控制台并执行此操作来查看大小:
show dbs
# pick yours (e.g., production)
use db-production
db.articles.stats()
我最终得到了这样的结果:
{
"ns" : "mdalert-production.encounters",
"count" : 89077,
"size" : 62974416,
"avgObjSize" : 706.9660630690302,
"storageSize" : 85170176,
"numExtents" : 8,
"nindexes" : 6,
"lastExtentSize" : 25819648,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 18808832,
"indexSizes" : {
"_id_" : 3719168,
"patient_num_1" : 3440640,
"msg_timestamp_1" : 2981888,
"practice_id_1" : 2342912,
"patient_id_1" : 3342336,
"msg_timestamp_-1" : 2981888
},
"ok" : 1
}
答案 3 :(得分:0)
如果游标批处理大小太大,则会导致此错误。设置批处理大小不会限制您可以处理的数据量,它只会限制从数据库返回的数据量。当您迭代并达到批量限制时,该过程将再次访问数据库。