Search code examples
mongodbsortingsymfonydoctrine-odmodm

How can I sort the results of a map/reduce using Doctrine ODM


I'm having an issue trying to sort after a map reduce. The collection has statistics (like scores) with users attached, so it's finding the highest score of the user. That portion works, the sort is to then sort those results for a leaderboard. I've put these functions into javascript variables and run them in the mongo console and a simple find().sort({'value.max.value':-1}) works fine on the resulting collection but I can't get it to work here. (My results come back unordered).

$query->map('function() { 
    var x = { value : parseInt(this.value), _id : this._id, date : this.postDate };
    emit(this.user, { max : x }); 
}')
->reduce('function(key, vals) {
    var res = vals[0];
    for (var i=1; i<vals.length; i++) 
    {
        if(vals[i].max.value > res.max.value)
            res.max = vals[i].max;
    }
    return res;
}')
->sort('value.max.value', 'desc');

Solution

  • When you do a ->map or ->reduce call, Doctrine internally switch the "query mode" from "find" mode to "mapreduce" mode.

    So you are actually doing a mapReduce MongoDB command as in the MongoDB Documentation

    This means that your sort() call is translated to a sort property in the mapReduce command, and so it sorts only the input documents.

    To actually sort the output you have 2 options:

    • Use the out() method in the query to output the results to a temporary Collection, then query the data from there with sort
    • Sort the results in php