“对于小型集合,sort()”的数据太多了

时间:2014-07-07 08:53:53

标签: mongodb mongodb-query

当尝试对mongodb集合进行查找和排序时,我得到以下错误。该集合根本不大 - 我只有28个文档,当我超过23个记录的限制时,我开始收到此错误。

该文档的特殊之处在于它内部包含一个大型ArrayCollection但我根本没有获取该特定字段,我只是想获取一个DateTime字段。

db.ANEpisodeBreakdown.find({creationDate: {$exists:true}}, {creationDate: true} ).limit(23).sort( { creationDate: 1}

{ "$err" : "too much data for sort() with no index. add an index or specify a smaller limit", "code" : 10128 }

3 个答案:

答案 0 :(得分:1)

所以这里的问题是32MB限制,你没有可以用作“仅索引”或“覆盖”查询的索引来获得结果。如果没有这个,你的“大字段”仍会被加载到数据中进行排序。

易于复制;

var string = "";
for ( var n=0; n < 10000000; n++ ) {
   string += 0;
}

for ( var x=0; x < 4; x++ ) {
    db.large.insert({ "large": string, "date": new Date() });
    sleep(1000);
}

所以这个查询会爆炸,除非你限制为3:

db.large.find({},{ "date": 1 }).sort({ "date": -1 })

要克服这个问题:

  1. 在日期(以及其他使用过的字段)上创建索引,以便在覆盖的索引查询中不加载整个文档:

    db.large.ensureIndex({ "date": 1 })
    db.large.find({},{ "_id": 0, "date": 1 }).sort({ "date": -1 })
    
    { "date" : ISODate("2014-07-07T10:08:33.067Z") }
    { "date" : ISODate("2014-07-07T10:08:31.747Z") }
    { "date" : ISODate("2014-07-07T10:08:30.391Z") }
    { "date" : ISODate("2014-07-07T10:08:29.038Z") }
    
  2. 请不要索引和使用聚合,因为$project不会受到与文档在传递给$sort之前实际更改相同的限制。

    db.large.aggregate([
        { "$project": { "_id": 0, "date": 1 }},
        { "$sort": {"date": -1 }}
    ])
    
    { "date" : ISODate("2014-07-07T10:08:33.067Z") }
    { "date" : ISODate("2014-07-07T10:08:31.747Z") }
    { "date" : ISODate("2014-07-07T10:08:30.391Z") }
    { "date" : ISODate("2014-07-07T10:08:29.038Z") }
    
  3. 无论哪种方式都可以获得限制下的结果,而无需以任何方式修改游标限制。

答案 1 :(得分:0)

如果没有索引,您可以用于排序的大小只会扩展到shellBatchSize,默认情况下为20。

DBQuery.shellBatchSize = 23;

这应该可以解决问题。

答案 2 :(得分:0)

问题是在这个特定场景中的投影仍然会加载整个文档,它只是将它发送到您的应用程序而没有大型数组字段。

因此,MongoDB仍在为其32mb限制排序太多数据。