使用内联结果在Map / Reduce之后排序

时间:2012-03-30 23:17:22

标签: mongodb mapreduce

在尝试了这个solution之后又向前迈了一步,我还有另外一个关于mongodb的问题。

我的问题是:

如何对输出进行排序:

doc = {_id : 16, days : { 1 : 123, 2 : 129, 3 : 140, 4 : 56, 5 : 57, 6 : 69, 7 : 80 }};
db.so.insert(doc);

map = function() {
  emit(this._id, this.days["1"]);
  emit(this._id, this.days["3"]); 
  emit(this._id, this.days["7"]); 
}

reduce = function (k, vals) {
  var sum = 0;
  vals.forEach(function (v) {sum += v;});
  return sum;
}

res = db.so.mapReduce(map, reduce, {out : {inline : 1}});
res.find();

输出是这样的:

"results" : [
    {
            "_id" : 16,
            "value" : 225
    },
    {
            "_id" : 33,
            "value" : 230
    },
    {
            "_id" : 302,
            "value" : 274
    }

现在我想用以下结果对结果进行排序:

res.find().sort({ "results.value":-1 });

会导致此错误:

Sat Mar 31 01:15:45 TypeError: res.find().sort({'results.value':-1}) is not a function (shell):1

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:6)

使用inline结果时,这不起作用。相反,尝试写入集合,然后对该集合运行排序。

res = db.so.mapReduce(map, reduce, {out : "tmpResults"});
db.tmpResult.find().sort({value:-1});

答案 1 :(得分:6)

以下是使用MongoDB 2.2 Aggregation Framework

的相同查询的示例
db.so.aggregate(
  { $project : {
     '_id' : 1,
     'value' : { $add : ["$days.1","$days.3","$days.7"] },
  }},
  { $sort: { 'value': -1 }}
)

..和输出:

{
    "result" : [
        {
            "_id" : 302,
            "value" : 274
        },
        {
            "_id" : 33,
            "value" : 230
        },
        {
            "_id" : 16,
            "value" : 225
        }
    ],
    "ok" : 1
}

答案 2 :(得分:5)

您可以对results属性进行完全排序:

res = db.so.mapReduce(map, reduce, {out : {inline : 1}});
res.results.sort(function (a, b) {
    if (a.value == b.value) {
        return 0;
    }
    return a.value < b.value ? -1 : 1;
});