达到具有索引的字段的排序限制

时间:2014-10-03 11:50:11

标签: java mongodb sorting mongo-java

我正在尝试按两个字段“start”和“end”对光标进行排序。他们俩都有索引。

这是尝试排序的代码。

    DBCursor cursor = store.colConcepts.find(q);
    cursor.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
    BasicDBObject sortObj = new BasicDBObject( "start", filter.isEventTimeSortDirAscending() ? 1 : -1 ).append( "end", filter.isEventTimeSortDirAscending() ? 1 : -1 ); 
    cursor = cursor.sort( sortObj );

在上面的代码中,查询q是{ "tags" : { "$all" : [ "Person"]}}

以下是关于集合store.colConcepts的索引。

        colConcepts.ensureIndex(new BasicDBObject("tags", 1));
        colConcepts.ensureIndex(new BasicDBObject("roles.concept",1));
        colConcepts.ensureIndex(new BasicDBObject("keys",1));
        colConcepts.ensureIndex(new BasicDBObject("start", 1));
        colConcepts.ensureIndex(new BasicDBObject("end", 1));

以下是cursor.explain()的结果。

{ "cursor" : "BtreeCursor tags_1" , "isMultiKey" : true , "n" : 237267 , "nscannedObjects" : 237267 , "nscanned" : 237267 , "nscannedObjectsAllPlans" : 237267 , "nscannedAllPlans" : 
237267 , "scanAndOrder" : false , "indexOnly" : false , "nYields" : 1853 , "nChunkSkips" : 0 , "millis" : 274 , "indexBounds" : { "tags" : [ [ "Person" , "Person"]]} , "allPlans" : [ 
{ "cursor" : "BtreeCursor tags_1" , "isMultiKey" : true , "n" : 237267 , "nscannedObjects" : 237267 , "nscanned" : 237267 , "scanAndOrder" : false , "indexOnly" : false , 
"nChunkSkips" : 0 , "indexBounds" : { "tags" : [ [ "Person" , "Person"]]}}] , "server" : "xxx:27017" , "filterSet" : false , "stats" : { "type" : "FETCH" , "works" : 237269 , 
"yields" : 1853 , "unyields" : 1853 , "invalidates" : 0 , "advanced" : 237267 , "needTime" : 1 , "needFetch" : 0 , "isEOF" : 1 , "alreadyHasObj" : 0 , "forcedFetches" : 0 , 
"matchTested" : 0 , "children" : [ { "type" : "IXSCAN" , "works" : 237268 , "yields" : 1853 , "unyields" : 1853 , "invalidates" : 0 , "advanced" : 237267 , "needTime" : 1 , 
"needFetch" : 0 , "isEOF" : 1 , "keyPattern" : "{ tags: 1 }" , "isMultiKey" : 1 , "boundsVerbose" : "field #0['tags']: [\"Person\", \"Person\"]" , "yieldMovedCursor" : 0 , 
"dupsTested" : 237267 , "dupsDropped" : 0 , "seenInvalidated" : 0 , "matchTested" : 0 , "keysExamined" : 237267 , "children" : [ ]}]}}

正如你可以看到标签,开始,结束所有标签都有索引。

执行时会产生异常:

com.mongodb.MongoException: Runner error: Overflow sort stage buffered data usage of 33554442 bytes exceeds internal limit of 33554432 bytes

我对这个问题进行了一些研究,发现如果你没有该领域的索引,就会出现这个问题。或者如果字段被索引为稀疏的,那么我的情况并非如此。

我正在使用mongodb 2.6.1。我确实使用2.6.4运行代码,但这并没有阻止mongo抛出异常。

知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

您没有正确的查询索引。查询计划程序选择了tags上的索引来完成查询,但该索引对排序没有帮助。由于您要根据标记进行选择,然后对其进行排序(startend),请尝试在{ "tags" : 1, "start" : 1, "end" : 1 }上添加索引。单独索引每个都没有帮助。