我在CouchDB中有一个示例数据库,其中包含许多飞机的信息,以及显示制造商作为关键和模型作为值的视图。
map函数
function(doc) {
emit(doc["Manufacturer"], doc._id)
}
, reduce函数为
function(keys, values, rereduce){
return values.length;
}
这很简单。当我使用Futon显示视图时,我确实得到了正确的结果,其中我有26架波音飞机:
"BOEING" 26
但是如果我使用REST客户端使用
查询视图http://localhost:6060/aircrafts/_design/basic/_view/VendorProducts?key="BOEING"
我{"rows":[
{"key":null,"value":2}
]}
我已经测试了不同的客户端(包括web浏览器,REST客户端扩展,和curl),所有给我的值2!而使用其他键的查询可以正常工作
是否有问题与MapReduce功能或我的查询?
问题可能是由于分组
使用group=true(这是Futon的默认值),您将为映射中的每个唯一键获得单独的reduce值—也就是说,共享相同键的所有值被分组在一起并简化为单个值。
当使用curl等查询时,您是否将group=true
作为查询参数传递?由于它是在futon中默认传递的,因此您看到的结果如下
BOEING: 26
如果没有group=true
,则只返回简化后的值。
所以试试这个查询
http://localhost:6060/aircrafts/_design/basic/_view/VendorProducts?key="BOEING"&group=true
你似乎掉进了re-reduce
陷阱。严格来说,Couchdb使用map-reduce- reduce过程。
- Map:以输出格式重新格式化数据。
- Reduce:聚合几个(但不是所有具有相同键的条目)的数据-在您的情况下可以正确工作。
- rereduce:执行与reduce相同的操作,但对先前减少的数据执行。
当您在reduce阶段更改值的格式时,rereduce调用将聚合已经减少的值的数量。
解决方案:
- 您可以将地图中的值设置为1并减少值的总和。
- 您检查
rereduce==true
,在这种情况下返回值的总和-这将是由初始减少返回的整数值。