降序排序时的 CouchDB 空值
CouchDB null value when sort descending
我有 CouchDB 视图,它按自然顺序为我提供了正确的值,在降序排序时为 null,这是 Futon 屏幕截图:
查看代码如下:
"informe_precios": {
"map": "function(doc){if(doc.doc_type=='precio'){emit([doc.comprador,doc.fecha.substr(0,4),doc.fecha.substr(5,2)],{precio:doc.precio,litros:doc.litros});}}",
"reduce": "function(keys, values, rereduce){var importe= 0; var totallitros = 0;for(var i = 0; i < values.length; i++) {importe += values[i].precio*values[i].litros;totallitros += values[i].litros;}return importe/totallitros;}"
}
我需要它降序,因为我想获得最后 12 个值。
TIA
迭戈
你总是假设你的 reduce
函数是用你的 map
函数的输出调用的,即。你没有处理 rereduce
情况。
在 rereduce
中,您的 values
将是之前 reduce
调用的 importe/totallitros
值。
您的 reduce 函数每个月的平均值为 "price per liter",因此因为它是平均值,所以您的 rereduce
函数无法实际处理该数据,因为对于多个 values
进来没办法知道他们的平均体重。
因此,您需要将函数更改为 return 计数,以便您可以使用它来加权 rereduce
函数中的平均值(我们还使用内置 sum
函数使事情变得更简单):
function(keys, values, rereduce) {
if (rereduce) {
var length = sum(values.map(function(v){return v[1]}));
var avg = sum(values.map(function(v){
return v[0] * (v[1] / length)
}));
return [avg, length];
}
else {
var importe= 0;
var totallitros = 0;
for( var i = 0; i < values.length; i++) {
importe += values[i].precio * values[i].litros;
totallitros += values[i].litros;
}
return [ importe/totallitros, values.length ];
}
}
您将在此处的视图中看到的最终结果是一个数组,因此您始终需要在客户端代码中挑选出它的第一个元素。
我有 CouchDB 视图,它按自然顺序为我提供了正确的值,在降序排序时为 null,这是 Futon 屏幕截图:
查看代码如下:
"informe_precios": {
"map": "function(doc){if(doc.doc_type=='precio'){emit([doc.comprador,doc.fecha.substr(0,4),doc.fecha.substr(5,2)],{precio:doc.precio,litros:doc.litros});}}",
"reduce": "function(keys, values, rereduce){var importe= 0; var totallitros = 0;for(var i = 0; i < values.length; i++) {importe += values[i].precio*values[i].litros;totallitros += values[i].litros;}return importe/totallitros;}"
}
我需要它降序,因为我想获得最后 12 个值。
TIA 迭戈
你总是假设你的 reduce
函数是用你的 map
函数的输出调用的,即。你没有处理 rereduce
情况。
在 rereduce
中,您的 values
将是之前 reduce
调用的 importe/totallitros
值。
您的 reduce 函数每个月的平均值为 "price per liter",因此因为它是平均值,所以您的 rereduce
函数无法实际处理该数据,因为对于多个 values
进来没办法知道他们的平均体重。
因此,您需要将函数更改为 return 计数,以便您可以使用它来加权 rereduce
函数中的平均值(我们还使用内置 sum
函数使事情变得更简单):
function(keys, values, rereduce) {
if (rereduce) {
var length = sum(values.map(function(v){return v[1]}));
var avg = sum(values.map(function(v){
return v[0] * (v[1] / length)
}));
return [avg, length];
}
else {
var importe= 0;
var totallitros = 0;
for( var i = 0; i < values.length; i++) {
importe += values[i].precio * values[i].litros;
totallitros += values[i].litros;
}
return [ importe/totallitros, values.length ];
}
}
您将在此处的视图中看到的最终结果是一个数组,因此您始终需要在客户端代码中挑选出它的第一个元素。