0

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');
John
  • 590
  • 4
  • 13

2 Answers2

1

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
Madarco
  • 2,084
  • 18
  • 26
  • Thanks for the explanation. Hopefully next time I dive into doctrine they have the aggregation framework supported. – John Apr 30 '13 at 14:16
0

The sort of a map-reduce is applied to the input documents (as fed to map), not the result. If you want to sort the results of the map-reduce you'd need to output to a collection and then perform a sorted find query on that collection (as you've successfully tried).

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471