javascript - 如何使用 CouchDB 的 reduce() 函数?

标签 javascript mapreduce couchdb

我正在尝试汇总我在 CouchDB 中的一些数据。数据库中有照片文件,数据库中有评级文件。每个评级文档看起来像这样(没有 _id 和 _rev):

{
   "type": "rating",
   "rating": 3 // Integer values are identifiers that map to a string; e.g 1 might mean 'funny'
   "photo": "as9i83ufsafa09uj" // The id of the photo that this rating points to.
}

我想要做的是计算每张照片的每种评级类型。
{
   "key": "as9i83ufsafa09uj", "value": [1, 7, 8, 6] // 1 '0' rating, 7 '1' ratings, etc.
   "key": "photoid2", "value": [3, 0, 0, 8]
}

我正在使用 CouchDB View 的 MapReduce 来实现这种聚合。
"map": "function(doc) {
   if(doc.type == 'rating')
   {
      emit(doc.photo, doc.rating);
   }
}",

"reduce": "function(keys, values, rereduce) {
   var result = new Array(0, 0, 0, 0);

   values.forEach( function(key, value)
   {
      result[value]+=1;
   });

   return result;
}"

map 返回:
{"total_rows":55,"offset":0,"rows":[
{"id":"0aa2c4c9a031eedbcf2795cabc1679be","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":0},
{"id":"29f363432e008f5934b4160292e18680","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":3},
{"id":"646d0d764623bc2f3ed1354ac03b583e","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":2},
...
{"id":"fa5be78402171e3bf1eb1cf91c5fda6e","key":"c63b78b6-ad92-426c-ab64-c9a6ae229b31","value":1}
]}

在 group_level=0 的情况下,reduce 返回:
{"rows":[
{"key":null,"value":[1,1,1,1]}
]}

组级别=1:
{"rows":[
{"key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":[2,2,2,0]},
{"key":"5ad3de4b-d25b-42d3-95e0-df7661becbf3","value":[2,2,2,2]},
{"key":"7600710b-9ae3-4312-876c-ad352722dac3","value":[2,2,2,2]},
{"key":"959f48a2-5018-4938-aab4-086d8824dd75","value":[2,0,0,0]},
{"key":"c63b78b6-ad92-426c-ab64-c9a6ae229b31","value":[2,2,2,2]}
]}

我熟悉 MongoDB 的 map reduce,这个函数可以使用他们的模式。我需要调整什么才能在 CouchDB 中工作?

更新
这是对我有用的最后一个 reduce 函数。我没有正确处理 rereduce 参数。感谢 Marcin Skórzewski 帮助我更好地理解 rereduce。
"reduce": "function(key, values, rereduce) {

        var result = new Array(0, 0, 0, 0);

        if(rereduce == true)
        {
            for(var i = 0; i < values.length; i++)
            {
                var value = values[i];

                for (var j = 0; j < value.length; j++)
                {
                    result[j] += value[j];
                }
            }

            return result;
        }

        for(var i = 0; i < values.length; i++)
        {
            value = values[i];
            result[value]+=1;
        }

        return result;

        }"

最佳答案

我认为你没有使用 rereduce适本地。 values元素和返回的数据不是同一类型。如果只有一个组级别和小数据量(以适合单个 B 树节点),它可以正常工作,因为不必运行 rereduce。看看reduce docrereduce 的含义reduce() 的参数.

万一reduce()针对从 map() 发出的值运行它们是整数,但如果减少先前 reduce() 获得的值它们是数组。您可以使用 rereduce如果是 true添加数组。或者您可以在 map 中发出数组(例如,获取 [0,0,0,1] 而不是 3 )并始终在 reduce() 中添加数组不用担心rereduce争论。

关于javascript - 如何使用 CouchDB 的 reduce() 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12852467/

相关文章:

hadoop - 如何从映射器向驱动程序报告一个值?

hadoop - 自定义 WritableCompare 将对象引用显示为输出

javascript - CouchDB:获取唯一值

python - 从旧数据库复制到 Couchdb 中的新数据库

javascript - Jquery 在点击事件而不是提交时验证

javascript - 显示外部网站 iframe 的内容并防止 Framekilling

javascript - Node.js - 模块缓存、部分完成的对象和循环依赖?

javascript - 我可以将 jstree 复选框限制为只有有 child 的 parent 吗?

mongodb - 如何删除mapReduce中的 "value"?

couchdb - 在 Cloudant 中的 _all_docs 查询中排除设计文档