Я использую CouchDB довольно долго без каких-либо проблем. Это до сих пор. Недавно я увидел на своей карте что-то / уменьшил результаты, которые я пропустил!
Это перед выполнением sum
для переменной "avgs". Я в основном пытаюсь найти среднее значение всех значений, относящихся к определенному ключу. Ничего фантастического. Результат, как и ожидалось.
Обратите внимание на результат для отметки времени 1308474660000 (4-я строка в таблице):
Теперь я sum
массив "avgs". Теперь вот что-то особенное в результате. Сумма для ключа с отметкой времени 1308474660000 составляет null
!! Почему CouchDB выплевывает null
с для простого sum
? Я попытался с пользовательской функцией сложения и ее же проблема.
Может кто-нибудь объяснить мне, почему эта проблема связана с моей картой / уменьшить результат?
Версия CouchDB: 1.0.1
UPDATE:
После восстановления я получаю ошибку уменьшения переполнения!
Error: reduce_overflow_error
Reduce output must shrink more rapidly: Current output: '["001,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,1,11,1,1,1,1,1,101,1,1,1,1,1,1,11,1,1,1,1'... (first 100 of 396 bytes)
Это моя модифицированная функция уменьшения:
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return avgs;
} else {
return sum(values);
};
}
ОБНОВЛЕНИЕ 2:
Ну, теперь стало еще хуже. Его выборочно уменьшать. Кроме того, те, которые были восстановлены, показывают неправильные результаты. Длина значения в 4-й строке для отметки времени (1308474660000) должна быть 2, а не 3.
ОБНОВЛЕНИЕ 3:
Я наконец получил его на работу. Я не понял специфику восстановления правильно. AFAIK, Couchdb сама решает, как / когда переопределить. В этом примере всякий раз, когда массив был достаточно длинным для обработки, Couchdb отправлял его для восстановления. Таким образом, я в основном должен был sum
дважды. Однажды в уменьшении, и снова в уменьшении.
function (key, values, rereduce) {
if(!rereduce) {
var avgs = [];
for(var i=values.length-1; i>=0 ; i--) {
avgs.push(Number(values[i][0])/Number(values[i][1]));
}
return sum(avgs);
} else {
return sum(values); //If my understanding of rereduce is correct, it only receives only the avgs that are large enough to not be processed by reduce.
}
}