地图/减少散列CouchDB中的阵列上
-
20-09-2019 - |
题
我要寻找一个映射/降低函数来计算在一个设计文件的状态。 下面你可以从我的当前数据库查看示例文件。
{
"_id": "0238f1414f2f95a47266ca43709a6591",
"_rev": "22-24a741981b4de71f33cc70c7e5744442",
"status": "retrieved image urls",
"term": "Lucas Winter",
"urls": [
{
"status": "retrieved",
"url": "http://...."
},
{
"status": "retrieved",
"url": "http://..."
}
],
"search_depth": 1,
"possible_labels": {
"gender": "male"
},
"couchrest-type": "SearchTerm"
}
我想摆脱status
关键的和而从URL的状态计算。
我的当前by_status
视图看起来如下:
function(doc) {
if (doc['status']) {
emit(doc['status'], null);
}
}
我尝试了一些东西,但没有任何实际工作。现在我Map Function
看起来是这样的:
function(doc) {
if(doc.urls){
emit(doc._id, doc.urls)
}
}
和我的Reduce Function
function(key, value, rereduce){
var reduced_status = "retrieved"
for(var url in value){
if(url.status=="new"){
reduced_status = "new";
}
}
return reduced_status;
}
结果是我得到检索到处是绝对不正确的。
我试图缩小问题,它似乎是value
没有阵列中,当我使用下面Reduce Function
我得到长度1无处不在,这是不可能的,因为我在我的数据库12页中的文件,20之间各自含有至200个网址
function(key, value, rereduce){
return value.length;
}
替代文字http://img.skitch.com/20100316-qeawxgd5pru8d5i6bprygcsmhf.jpg一>
我在做什么错了? (我知道我要你写的代码,我和我感到内疚,但现在我的状态的计算红宝石从数据库中获取数据后,这将是很好的获得已经从正确的数据数据库)
解决方案
的减少功能的可变value
是值的阵列由地图功能发射的。在你的情况,value
是由“URL” -arrays数组。当运行在蒲团的map-reduce,使地图,减少被seperately从地图功能发出的每一个关键运行设置group=true
。在你的情况下,这些按键是文档_ids
。即,减少功能的value
是数组,其元素是属于某文档_id所有URL阵列。由于DOC _ids都是独一无二的,你最终将减少功能的value
是与一个元素的数组,这个元素是各自的文档的URL阵列。这就是为什么value.length
始终为1与减少功能。
但它可以变得更糟:如果您在rereduce周期结束时,减少功能的value
是由先前调用减少函数返回值的数组。在你的情况,你会调用该函数减少与value
看起来像["retrieved","new","retrieved"]
,这不会导致正确的结果。
通常,降低功能被用于聚集由地图功能发射的数据,例如数行或总结值 - 这是没有必要的你的情况。你可以阅读更多CouchDB中有关的map-reduce这里:
http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views
其他提示
doc.urls
似乎是含有Object
特性和status
属性url
s数组。所以,你的Reduce函数应该是这样的。
function(key, value, rereduce){
var reduced_status = "retrieved";
for(var i=0; i<value.length; i++) {
if(value[i].status=="new"){
reduced_status = "new";
}
}
return reduced_status;
}
编辑:实际上,因为它找到status == "new"
功能应该尽快返回
感谢Alsciende推我朝着正确的解决方案,原来我真的不明白的降低作用。我并不需要一个减少功能都没有。
下面是我Map Function
解决了对我来说。
function(doc) {
if(doc.urls){
var reduced_status = "retrieved";
for(var i=0; i<doc.urls.length; i++) {
if(doc.urls[i].status=="new"){
reduced_status = "new";
break;
}
}
emit(reduced_status, null);
}
}