我有一个CouchDB数据库,其中的文档包含如下数据:
"field1": "text",
"field2": "text",
"field3":[14 54 23 24,25,26,23,19,17 etc.]
etc.
我正在尝试使用map reduce来获取数据库中所有field3值的平均值。
我做了如下地图:
function(doc) {
if(doc.field3){
emit(null,doc.field3);
}
}
和减少:
function (keys, values, rereduce) {
if (rereduce){
return sum(values);
} else {
return values.length;
}
}
或简单地说:
_sum
后者给出了一系列数字,这些数字似乎是数组中相同数字的总和。
Cloudant网站上有一个例子涉及访问一组数字,但不是完整的答案,我现在找不到它。
我还调查了CouchDB 2.0.0上的新'mango'
查询系统,它更容易设置,但我没有在文档中看到任何使用它进行计算的方法。
修改
允许我自由地加上这个问题,或许是一个很好的例子。
我正在使用Mockaroo生成数据并找到了另一种生成此数据的方法,这种方法更加真实,因为我可以改变数据的更多方面。
然而,这导致我的数组发生以下更改:
"field3":[{"item": 44}, {"item":23}, {"item": 36}, etc.]
使用@Alexis
提供的成功地图,我试图让它读取这些数据。例如:
function(doc) {
if(doc.field3[0].item >0){
if (doc.field3) {
if (Array.isArray(doc.field3))
for (var n in doc.field3)
emit(null, doc.field3[n].item);
}
}
}
我尝试了上述代码的多种变体,添加了.item
或[]
以及添加/删除if语句,但没有成功。
如果可能的话,我也非常感谢数组变体的帮助。
由于某种原因,在map / reduce中设置javascript并不容易。 我已经通过相当多的免费在线JavaScript学习课程来尝试使用CouchDB提高我的能力,但没有取得多大成功。 是否有更好的方法来学习为地图缩小编写正确的javascript的黑暗艺术?
非常感谢你的帮助。
答案 0 :(得分:1)
由于你希望field3上的全局平均值是一个数组,我首先会映射所有字段3的值并将它们全部减少。
地图功能:
function(doc) {
if (doc.field3) {
if (Array.isArray(doc.field3))
for (var n in doc.field3)
emit(null, doc.field3[n]);
}
}
减少功能:
function(keys, values, rereduce) {
return sum(values)/values.length;
}
新修改意味着新答案!
//Your function
function(doc) {
if (doc.field3[0].item > 0) {
if (doc.field3) {
if (Array.isArray(doc.field3))
for (var n in doc.field3)
emit(null, doc.field3[n].item);
}
}
}
//Fixed one
function(doc){
//We check if the field3 is an array and we check if its length is
//true. In javascript 0==false, any number ==true and the length can't
// be negative so we are in business.
if(Array.isArray(doc.field3) && doc.field3.length){
//Your array contains many object. So we can simply iterate through them
for(var i=0;i<doc.field3.length;i++){
//at this point, doc.field3[i] is one of the object. Eg: {"item":44}
emit(null,doc.field3[i].item);
}
}
}