В MongoDB, как я могу повторить этот простой запрос, используя map / lower в ruby? - PullRequest
0 голосов
/ 17 июня 2010

Итак, используя обычную библиотеку MongoDB в Ruby, у меня есть следующий запрос для определения среднего размера файла в наборе 5001 документов:

avg = 0
    total = collection.count()
    Rails.logger.info "#{total} asset creation stats in the system"
    collection.find().each {|row| avg += (row["filesize"] * (1/total.to_f)) if row["filesize"]}

Это довольно просто, поэтому я пытаюсь сделать то же самое, используяКарта / уменьшить как учебное упражнение.Вот что я придумал:

map = 'function(){emit("filesizes", {size: this.filesize, num: 1});}'
    reduce = 'function(k, vals){
            var result = {size: 0, num: 0};
            for(var x in vals) {
              var new_total = result.num + vals[x].num;
              result.num = new_total
              result.size = result.size + (vals[x].size * (vals[x].num / new_total));
            }
            return result;
    }'
    @results = collection.map_reduce(map, reduce)

Однако два запроса возвращаются с двумя разными результатами!

Что я делаю не так?

1 Ответ

1 голос
/ 17 июня 2010

Вы взвешиваете результаты, выполняя деление в каждой функции уменьшения.

Скажем, у вас было [{size : 5, num : 1}, {size : 5, num : 1}, {size : 5, num : 1}].Ваше уменьшение будет рассчитывать:

result.size = 0 + (5*(1/1)) = 5
result.size = 5 + (5*(1/2)) = 7.25
result.size = 7.25 + (5*(1/3)) = 8.9

Как вы можете видеть, это взвешивает результаты в отношении самых ранних элементов.Просто добавьте функцию финализации, которая будет запускаться один раз после завершения шага сокращения.

...