2012-03-30 3 views
4

Попытавшись сделать это 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 

ли кто-нибудь может мне помочь?

ответ

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 
} 
6

Это не будет работать таким образом с результатами inline. Вместо этого попробуйте написать коллекцию, а затем запустить сортировку в этой коллекции.

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

, вы думаете, что это будет возможно с новой структурой агрегации манго? – MadeOfSport

+0

Да, я считаю, что вы можете сделать это с помощью структуры агрегации. Похоже, вы '$ project'' _id' и 'sum', а затем используете' $ sort'. Это должно быть довольно легко проверить, так как 2.1 доступен для загрузки. –

+0

Вы правы. Это отлично работает – MadeOfSport

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; 
}); 
Смежные вопросы