我正在使用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()数据太多。添加索引或指定更小的限制)
我究竟做错了什么?
尝试添加{community_id: 1, 'updated_at.t': -1}
索引。它需要首先搜索community_id
然后排序。
所以它“感觉”就像你正在使用索引,但索引实际上是一个复合索引。我不确定排序是否“足够智能”才能使用部分索引。
所以有两个问题:
updated_at.t
听起来像一个你将在其上进行范围查询的字段。如果范围查询是第二位,则索引可以更好地工作。community_id => 1
会有多少参赛作品回来?如果数字不大,您可以在没有索引的情况下进行排序。所以你可能不得不切换索引,你可能不得不改变排序以使用community_id
和updated_at.t
。我知道这似乎是多余的,但从那里开始,检查Google网上论坛是否仍无效。
即使使用索引,我认为如果结果集超过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
}
如果游标批处理大小太大将导致此错误。设置批处理大小不会限制您可以处理的数据量,它只会限制从数据库返回的数据量。当您迭代并达到批量限制时,该过程将再次访问数据库。