Search code examples
mongodbmgo

Failing to get results with sort query in mgo


I'm trying to understand what's wrong with my use case. I'm trying to query MongoDB with mgo sort query like this:

conn := _Mongo.Connect() // custom mongo connection
defer conn.Close()
c := conn.DB(dbname).C(collname)
index := mgo.Index{
    Key:        skeys,
    Unique:     false,
    Background: true,
}
e := c.EnsureIndex(index)
if e != nil {
   panic(e)
}
err := c.Find(spec).Sort(skeys...).All(&out)

As you can see I do call ensure index on my passed selection keys (skeys). But during runtime for large queries I get the following error:

Executor error: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.

I checked that my collection indeed has an index, but it seems to me that mgo does not use it.

Thanks, Valentin.

P.S. Here is explain output from mongo for query in question:

Explain: bson.M{"queryPlanner":bson.M{"parsedQuery":bson.M{"$and":[]interface {}{bson.M{"das.record":bson.M{"$eq":1}}, bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}}}, "winningPlan":bson.M{"stage":"SORT", "sortPattern":bson.M{"dataset.name":1}, "inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", "inputStage":bson.M{"stage":"FETCH", "filter":bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}, "inputStage":bson.M{"isSparse":false, "isPartial":false, "indexVersion":2, "direction":"forward", "stage":"IXSCAN", "keyPattern":bson.M{"das.record":1}, "indexName":"das.record_1", "isMultiKey":false, "isUnique":false, "indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}}}}}, "rejectedPlans":[]interface {}{bson.M{"stage":"SORT", "sortPattern":bson.M{"dataset.name":1}, "inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", "inputStage":bson.M{"stage":"FETCH", "filter":bson.M{"das.record":bson.M{"$eq":1}}, "inputStage":bson.M{"keyPattern":bson.M{"qhash":1}, "indexName":"qhash_1", "isMultiKey":false, "isSparse":false, "stage":"IXSCAN", "isUnique":false, "isPartial":false, "indexVersion":2, "direction":"forward", "indexBounds":bson.M{"qhash":[]interface {}{"[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"}}}}}}, bson.M{"stage":"SORT", "sortPattern":bson.M{"dataset.name":1}, "inputStage":bson.M{"stage":"KEEP_MUTATIONS", "inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", "inputStage":bson.M{"stage":"FETCH", "inputStage":bson.M{"stage":"AND_SORTED", "inputStages":[]interface {}{bson.M{"keyPattern":bson.M{"qhash":1}, "isPartial":false, "indexVersion":2, "indexBounds":bson.M{"qhash":[]interface {}{"[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"}}, "direction":"forward", "stage":"IXSCAN", "indexName":"qhash_1", "isMultiKey":false, "isUnique":false, "isSparse":false}, bson.M{"stage":"IXSCAN", "isMultiKey":false, "isUnique":false, "isSparse":false, "isPartial":false, "direction":"forward", "indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}, "keyPattern":bson.M{"das.record":1}, "indexName":"das.record_1", "indexVersion":2}}}}}}}, bson.M{"sortPattern":bson.M{"dataset.name":1}, "inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", "inputStage":bson.M{"stage":"FETCH", "filter":bson.M{"$and":[]interface {}{bson.M{"das.record":bson.M{"$eq":1}}, bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}}}, "inputStage":bson.M{"direction":"forward", "keyPattern":bson.M{"dataset.name":1}, "indexName":"dataset.name_1", "isMultiKey":true, "isSparse":false, "indexBounds":bson.M{"dataset.name":[]interface {}{"[MinKey, MaxKey]"}}, "stage":"IXSCAN", "isUnique":false, "isPartial":false, "indexVersion":2}}}, "stage":"SORT"}}, "plannerVersion":1, "namespace":"das.cache", "indexFilterSet":false}, "executionStats":bson.M{"executionTimeMillis":317, "totalDocsExamined":30972, "executionSuccess":false, "errorMessage":"Exec error resulting in state FAILURE :: caused by :: errmsg: \"Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.\"", "totalKeysExamined":30972, "executionStages":bson.M{"isEOF":0, "sortPattern":bson.M{"dataset.name":1}, "needTime":30973, "saveState":497, "nReturned":0, "restoreState":497, "executionTimeMillisEstimate":150, "memLimit":33554432, "advanced":0, "needYield":0, "invalidates":0, "memUsage":33554660, "inputStage":bson.M{"advanced":30972, "needTime":1, "saveState":497, "restoreState":497, "isEOF":0, "invalidates":0, "inputStage":bson.M{"stage":"FETCH", "works":30972, "restoreState":497, "invalidates":0, "alreadyHasObj":0, "inputStage":bson.M{"dupsDropped":0, "seenInvalidated":0, "stage":"IXSCAN", "needTime":0, "isMultiKey":false, "indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}, "keysExamined":30972, "direction":"forward", "restoreState":497, "isEOF":0, "indexName":"das.record_1", "isSparse":false, "indexVersion":2, "seeks":1, "dupsTested":0, "executionTimeMillisEstimate":35, "advanced":30972, "needYield":0, "saveState":497, "keyPattern":bson.M{"das.record":1}, "nReturned":30972, "works":30972, "invalidates":0, "isUnique":false, "isPartial":false}, "saveState":497, "filter":bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}, "advanced":30972, "isEOF":0, "docsExamined":30972, "nReturned":30972, "executionTimeMillisEstimate":68, "needTime":0, "needYield":0}, "stage":"SORT_KEY_GENERATOR", "nReturned":30972, "executionTimeMillisEstimate":138, "works":30973, "needYield":0}, "stage":"SORT", "works":30974}, "allPlansExecution":[]interface {}{bson.M{"nReturned":0, "executionTimeMillisEstimate":69, "totalKeysExamined":10491, "totalDocsExamined":10491, "executionStages":bson.M{"stage":"SORT", "executionTimeMillisEstimate":69, "works":10492, "restoreState":335, "isEOF":0, "memUsage":11812527, "inputStage":bson.M{"advanced":10491, "needTime":1, "saveState":335, "restoreState":335, "isEOF":0, "stage":"SORT_KEY_GENERATOR", "executionTimeMillisEstimate":69, "works":10492, "invalidates":0, "inputStage":bson.M{"needTime":0, "invalidates":0, "isEOF":0, "docsExamined":10491, "alreadyHasObj":0, "stage":"FETCH", "filter":bson.M{"das.record":bson.M{"$eq":1}}, "advanced":10491, "needYield":0, "saveState":335, "inputStage":bson.M{"invalidates":0, "isMultiKey":false, "seeks":1, "dupsTested":0, "needTime":0, "isEOF":0, "works":10491, "needYield":0, "restoreState":335, "keyPattern":bson.M{"qhash":1}, "indexName":"qhash_1", "isSparse":false, "stage":"IXSCAN", "nReturned":10491, "seenInvalidated":0, "indexVersion":2, "indexBounds":bson.M{"qhash":[]interface {}{"[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"}}, "advanced":10491, "isPartial":false, "isUnique":false, "direction":"forward", "keysExamined":10491, "dupsDropped":0, "executionTimeMillisEstimate":10, "saveState":335}, "nReturned":10491, "executionTimeMillisEstimate":55, "works":10491, "restoreState":335}, "nReturned":10491, "needYield":0}, "needTime":10492, "memLimit":33554432, "nReturned":0, "advanced":0, "needYield":0, "saveState":335, "invalidates":0, "sortPattern":bson.M{"dataset.name":1}}}, bson.M{"nReturned":0, "executionTimeMillisEstimate":11, "totalKeysExamined":10491, "totalDocsExamined":5245, "executionStages":bson.M{"restoreState":335, "inputStage":bson.M{"saveState":335, "restoreState":335, "inputStage":bson.M{"nReturned":5245, "executionTimeMillisEstimate":11, "advanced":5245, "needYield":0, "restoreState":335, "invalidates":0, "inputStage":bson.M{"isEOF":0, "alreadyHasObj":0, "works":10491, "needTime":5246, "restoreState":335, "advanced":5245, "saveState":335, "nReturned":5245, "needYield":0, "invalidates":0, "inputStage":bson.M{"stage":"AND_SORTED", "executionTimeMillisEstimate":0, "works":10491, "saveState":335, "advanced":5245, "needTime":5246, "nReturned":5245, "needYield":0, "isEOF":0, "flagged":0, "restoreState":335, "invalidates":0, "failedAnd_0":0, "failedAnd_1":0, "inputStages":[]interface {}{bson.M{"stage":"IXSCAN", "nReturned":5246, "invalidates":0, "isUnique":false, "keysExamined":5246, "dupsDropped":0, "seeks":1, "dupsTested":0, "executionTimeMillisEstimate":0, "advanced":5246, "restoreState":335, "keyPattern":bson.M{"qhash":1}, "indexName":"qhash_1", "indexVersion":2, "indexBounds":bson.M{"qhash":[]interface {}{"[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"}}, "needTime":0, "needYield":0, "saveState":335, "isEOF":0, "isMultiKey":false, "direction":"forward", "works":5246, "isSparse":false, "isPartial":false, "seenInvalidated":0}, bson.M{"advanced":5245, "isEOF":0, "indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}, "seeks":1, "stage":"IXSCAN", "nReturned":5245, "needTime":0, "needYield":0, "isSparse":false, "indexVersion":2, "isPartial":false, "direction":"forward", "executionTimeMillisEstimate":0, "works":5245, "saveState":335, "invalidates":0, "keyPattern":bson.M{"das.record":1}, "isMultiKey":false, "keysExamined":5245, "restoreState":335, "indexName":"das.record_1", "isUnique":false, "dupsTested":0, "dupsDropped":0, "seenInvalidated":0}}}, "stage":"FETCH", "executionTimeMillisEstimate":11, "docsExamined":5245}, "stage":"SORT_KEY_GENERATOR", "works":10492, "needTime":5247, "saveState":335, "isEOF":0}, "stage":"KEEP_MUTATIONS", "nReturned":5245, "needYield":0, "needTime":5247, "isEOF":0, "invalidates":0, "executionTimeMillisEstimate":11, "works":10492, "advanced":5245}, "executionTimeMillisEstimate":11, "works":10492, "needYield":0, "invalidates":0, "memUsage":6102195, "stage":"SORT", "nReturned":0, "advanced":0, "needTime":10492, "saveState":335, "isEOF":0, "sortPattern":bson.M{"dataset.name":1}, "memLimit":33554432}}, bson.M{"nReturned":0, "executionTimeMillisEstimate":70, "totalKeysExamined":10491, "totalDocsExamined":10491, "executionStages":bson.M{"executionTimeMillisEstimate":70, "saveState":335, "sortPattern":bson.M{"dataset.name":1}, "works":10492, "inputStage":bson.M{"advanced":10485, "needYield":0, "executionTimeMillisEstimate":58, "works":10492, "needTime":7, "saveState":335, "restoreState":335, "isEOF":0, "invalidates":0, "inputStage":bson.M{"executionTimeMillisEstimate":36, "saveState":335, "docsExamined":10491, "nReturned":10485, "restoreState":335, "invalidates":0, "needYield":0, "filter":bson.M{"$and":[]interface {}{bson.M{"das.record":bson.M{"$eq":1}}, bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}}}, "advanced":10485, "alreadyHasObj":0, "stage":"FETCH", "needTime":6, "isEOF":0, "inputStage":bson.M{"keyPattern":bson.M{"dataset.name":1}, "isPartial":false, "indexVersion":2, "nReturned":10491, "executionTimeMillisEstimate":24, "advanced":10491, "saveState":335, "invalidates":0, "indexBounds":bson.M{"dataset.name":[]interface {}{"[MinKey, MaxKey]"}}, "dupsDropped":0, "seenInvalidated":0, "dupsTested":10491, "works":10491, "needTime":0, "isMultiKey":true, "isUnique":false, "keysExamined":10491, "needYield":0, "isEOF":0, "direction":"forward", "seeks":1, "stage":"IXSCAN", "restoreState":335, "indexName":"dataset.name_1", "isSparse":false}, "works":10491}, "stage":"SORT_KEY_GENERATOR", "nReturned":10485}, "stage":"SORT", "nReturned":0, "advanced":0, "memUsage":11787104, "needTime":10492, "needYield":0, "restoreState":335, "isEOF":0, "invalidates":0, "memLimit":33554432}}, bson.M{"executionTimeMillisEstimate":59, "totalKeysExamined":10491, "totalDocsExamined":10491, "executionStages":bson.M{"works":10492, "advanced":0, "needTime":10492, "isEOF":0, "invalidates":0, "sortPattern":bson.M{"dataset.name":1}, "restoreState":335, "memUsage":11812527, "inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", "works":10492, "advanced":10491, "inputStage":bson.M{"inputStage":bson.M{"isMultiKey":false, "isSparse":false, "indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}, "seeks":1, "advanced":10491, "needTime":0, "saveState":335, "indexName":"das.record_1", "dupsTested":0, "restoreState":335, "isPartial":false, "dupsDropped":0, "isUnique":false, "indexVersion":2, "direction":"forward", "keysExamined":10491, "stage":"IXSCAN", "nReturned":10491, "needYield":0, "isEOF":0, "seenInvalidated":0, "executionTimeMillisEstimate":11, "works":10491, "invalidates":0, "keyPattern":bson.M{"das.record":1}}, "stage":"FETCH", "works":10491, "advanced":10491, "isEOF":0, "invalidates":0, "alreadyHasObj":0, "filter":bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}, "nReturned":10491, "executionTimeMillisEstimate":21, "needTime":0, "needYield":0, "saveState":335, "restoreState":335, "docsExamined":10491}, "saveState":335, "restoreState":335, "isEOF":0, "invalidates":0, "nReturned":10491, "executionTimeMillisEstimate":47, "needTime":1, "needYield":0}, "stage":"SORT", "executionTimeMillisEstimate":59, "needYield":0, "nReturned":0, "saveState":335, "memLimit":33554432}, "nReturned":0}}, "errorCode":96, "nReturned":0}, "serverInfo":bson.M{"version":"3.6.3", "gitVersion":"9586e557d54ef70f9ca4b43c26892cd55257e1a5", "host":"vkair", "port":8230}}

In particular, it says:

"inputStage":bson.M{"direction":"forward", "keyPattern":bson.M{"dataset.name":1},
"indexName":"dataset.name_1", "isMultiKey":true, "isSparse":false, 
"indexBounds":bson.M{"dataset.name":[]interface {}{"[MinKey, MaxKey]"}},     
"stage":"IXSCAN", "isUnique":false, "isPartial":false, "indexVersion":2}}}, 
"stage":"SORT"}}, 
"plannerVersion":1, "namespace":"das.cache", "indexFilterSet":false}, 
"executionStats":bson.M{"executionTimeMillis":317, "totalDocsExamined":30972,
"executionSuccess":false,
"errorMessage":"Exec error resulting in state FAILURE :: caused by :: errmsg: \"Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.

P.S.S. The winning plan was (output from mgo):

"winningPlan":bson.M{"stage":"SORT", 
"sortPattern":bson.M{"dataset.name":1}, 
"inputStage":bson.M{"stage":"SORT_KEY_GENERATOR", 
"inputStage":bson.M{"stage":"FETCH", 
"filter":bson.M{"qhash":bson.M{"$eq":"7b32b92becab9b5de06fa8ac85011133"}}, 
"inputStage":bson.M{"isSparse":false, 
"isPartial":false, "indexVersion":2, 
"direction":"forward", "stage":"IXSCAN", 
"keyPattern":bson.M{"das.record":1}, 
"indexName":"das.record_1",
"isMultiKey":false, "isUnique":false, 
"indexBounds":bson.M{"das.record":[]interface {}{"[1, 1]"}}}}}}

and, output from mongo shell

                "winningPlan" : {
                    "stage" : "SORT",
                    "sortPattern" : {
                            "dataset.name" : 1
                    },
                    "inputStage" : {
                            "stage" : "SORT_KEY_GENERATOR",
                            "inputStage" : {
                                    "stage" : "FETCH",
                                    "filter" : {
                                            "qhash" : {
                                                    "$eq" : "7b32b92becab9b5de06fa8ac85011133"
                                            }
                                    },
                                    "inputStage" : {
                                            "stage" : "IXSCAN",
                                            "keyPattern" : {
                                                    "das.record" : 1
                                            },
                                            "indexName" : "das.record_1",
                                            "isMultiKey" : false,
                                            "isUnique" : false,
                                            "isSparse" : false,
                                            "isPartial" : false,
                                            "indexVersion" : 2,
                                            "direction" : "forward",
                                            "indexBounds" : {
                                                    "das.record" : [
                                                            "[1.0, 1.0]"
                                                    ]
                                            }
                                    }
                            }
                    }
            }

As far as I can tell the winning plans from mgo and mongo shell are the same. If I execute the same query in mongo shell I get the following:

> db.cache.find({"qhash":"7b32b92becab9b5de06fa8ac85011133", "das.record":1}).sort({"dataset.name":1})
Error: error: {
    "ok" : 0,
    "errmsg" : "Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.",
    "code" : 96,
    "codeName" : "OperationFailed"}

while if I do count aggregation, it returns results fast:

db.cache.find({"qhash":"7b32b92becab9b5de06fa8ac85011133", "das.record":1}).sort({"dataset.name":1}).count()
69936

so it seems like mongo itself has a problem with using winning plan (index) while fetching results.

update1 As Wan suggested I created new compound index

db.cache.createIndex({"qhash":1, "das.record":1, "dataset.name":1})

but it didn't solve the problem. If I place the query

db.cache.find({"qhash":"7b32b92becab9b5de06fa8ac85011133", "das.record":1}).sort({"dataset.name":1}).explain()

the winning plan is still uses das.record index, see

{
    "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "das.cache",
            "indexFilterSet" : false,
            "parsedQuery" : {
                    "$and" : [
                            {
                                    "das.record" : {
                                            "$eq" : 1
                                    }
                            },
                            {
                                    "qhash" : {
                                            "$eq" : "7b32b92becab9b5de06fa8ac85011133"
                                    }
                            }
                    ]
            },
            "winningPlan" : {
                    "stage" : "SORT",
                    "sortPattern" : {
                            "dataset.name" : 1
                    },
                    "inputStage" : {
                            "stage" : "SORT_KEY_GENERATOR",
                            "inputStage" : {
                                    "stage" : "FETCH",
                                    "filter" : {
                                            "qhash" : {
                                                    "$eq" : "7b32b92becab9b5de06fa8ac85011133"
                                            }
                                    },
                                    "inputStage" : {
                                            "stage" : "IXSCAN",
                                            "keyPattern" : {
                                                    "das.record" : 1
                                            },
                                            "indexName" : "das.record_1",
                                            "isMultiKey" : false,
                                            "isUnique" : false,
                                            "isSparse" : false,
                                            "isPartial" : false,
                                            "indexVersion" : 2,
                                            "direction" : "forward",
                                            "indexBounds" : {
                                                    "das.record" : [
                                                            "[1.0, 1.0]"
                                                    ]
                                            }
                                    }
                            }
                    }
            },
            "rejectedPlans" : [
                    {
                            "stage" : "SORT",
                            "sortPattern" : {
                                    "dataset.name" : 1
                            },
                            "inputStage" : {
                                    "stage" : "SORT_KEY_GENERATOR",
                                    "inputStage" : {
                                            "stage" : "FETCH",
                                            "filter" : {
                                                    "das.record" : {
                                                            "$eq" : 1
                                                    }
                                            },
                                            "inputStage" : {
                                                    "stage" : "IXSCAN",
                                                    "keyPattern" : {
                                                            "qhash" : 1
                                                    },
                                                    "indexName" : "qhash_1",
                                                    "isMultiKey" : false,
                                                    "isUnique" : false,
                                                    "isSparse" : false,
                                                    "isPartial" : false,
                                                    "indexVersion" : 2,
                                                    "direction" : "forward",
                                                    "indexBounds" : {
                                                            "qhash" : [
                                                                    "[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"
                                                            ]
                                                    }
                                            }
                                    }
                            }
                    },
                    {
                            "stage" : "SORT",
                            "sortPattern" : {
                                    "dataset.name" : 1
                            },
                            "inputStage" : {
                                    "stage" : "SORT_KEY_GENERATOR",
                                    "inputStage" : {
                                            "stage" : "FETCH",
                                            "inputStage" : {
                                                    "stage" : "IXSCAN",
                                                    "keyPattern" : {
                                                            "qhash" : 1,
                                                            "das.record" : 1,
                                                            "dataset.name" : 1
                                                    },
                                                    "indexName" : "qhash_1_das.record_1_dataset.name_1",
                                                    "isMultiKey" : true,
                                                    "isUnique" : false,
                                                    "isSparse" : false,
                                                    "isPartial" : false,
                                                    "indexVersion" : 2,
                                                    "direction" : "forward",
                                                    "indexBounds" : {
                                                            "qhash" : [
                                                                    "[\"7b32b92becab9b5de06fa8ac85011133\", \"7b32b92becab9b5de06fa8ac85011133\"]"
                                                            ],
                                                            "das.record" : [
                                                                    "[1.0, 1.0]"
                                                            ],
                                                            "dataset.name" : [
                                                                    "[MinKey, MaxKey]"
                                                            ]
                                                    }
                                            }
                                    }
                            }
                    },
                    {
                            "stage" : "SORT",
                            "sortPattern" : {
                                    "dataset.name" : 1
                            },
                            "inputStage" : {
                                    "stage" : "SORT_KEY_GENERATOR",
                                    "inputStage" : {
                                            "stage" : "FETCH",
                                            "filter" : {
                                                    "$and" : [
                                                            {
                                                                    "das.record" : {
                                                                            "$eq" : 1
                                                                    }
                                                            },
                                                            {
                                                                    "qhash" : {
                                                                            "$eq" : "7b32b92becab9b5de06fa8ac85011133"
                                                                    }
                                                            }
                                                    ]
                                            },
                                            "inputStage" : {
                                                    "stage" : "IXSCAN",
                                                    "keyPattern" : {
                                                            "dataset.name" : 1
                                                    },
                                                    "indexName" : "dataset.name_1",
                                                    "isMultiKey" : true,
                                                    "isUnique" : false,
                                                    "isSparse" : false,
                                                    "isPartial" : false,
                                                    "indexVersion" : 2,
                                                    "direction" : "forward",
                                                    "indexBounds" : {
                                                            "dataset.name" : [
                                                                    "[MinKey, MaxKey]"
                                                            ]
                                                    }
                                            }
                                    }
                            }
                    }
            ]
    },
    "serverInfo" : {
            "host" : "vkair",
            "port" : 8230,
            "version" : "3.6.3",
            "gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
    },
    "ok" : 1
}

Solution

  • Executor error: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.

    In MongoDB, sort operations can obtain the sort order by retrieving documents based on the ordering in an index. If the query planner cannot obtain the sort order from an index, it will sort the results in memory. Using an index to retrieve results in sorted order is more efficient than retrieving results and sorting in-memory. In addition, sort operations that do not use an index will abort when they use 32 megabytes of memory.

    Based on the output of explain you posted, this is because you have an index on das.record (winning plan, used for the query), however you're sorting based on dataset.name which either a) losing plan or b) there is no such index.

    An index can support sort operations on a non-prefix subset of the index key pattern. To do so, the query must include equality conditions on all the prefix keys that precede the sort keys. For example, if your query is :

    db.cache.find({"qhash":"7b32b92becab9b5de06fa8ac85011133", "das.record":1}).sort({"dataset.name":1})
    

    Then to utilise index for both filter and sort, you should have a compound index:

    {"qhash":1, "das.record":1, "dataset.name":1 }
    

    See more information on the manual Tutorial: sort and non-prefix subset of an index

    You may also benefit from reading: MongoDB Indexing Strategies and Blog: Optimizing MongoDB Compound Indexes

    As far as I can tell the winning plans from mgo and mongo shell are the same

    Given the same query the output should be the same. The reason I asked for output from the mongo shell is to remove the Go aspect, i.e. your code from the debugging layer.

    UPDATE:

    I created additional index { "v" : 2, "key" : { "qhash" : 1, "das.record" : 1, "dataset.name" : 1 }, "name" : "qhash_1_das.record_1_dataset.name_1", "ns" : "das.cache" } but the MongoDB does not use it

    Based on your explain output, you can find that the new index qhash_1_das.record_1_dataset.name_1 is listed under the rejectedPlan section. There are few potential reasons for this, but the likely cause in this case is that dataset.name is an array or has some array value. Indicated by isMultiKey:true and the index bound of min, max.

    This multikey index on dataset.name may have caused an undesired slowness, hence being rejected as the fastest query plan.

    If you don't intend to have value of arrays in dataset.name, find the offending documents and alter/remove the array values. In addition, you also need to recreate index qhash_1_das.record_1_dataset.name_1.

    If dataset.name actually contains arrays, sorting based on multi key is going to be less performant. You may have to remove the other indexes, choose another field with single value to sort, manipulate split the value of dataset.name, or redesign your dataset document structure.