繁体   English   中英

在CouchDB中映射/减少哈希数组

[英]Map/Reduce on an array of hashes in CouchDB

我正在寻找一种映射/归约函数来计算设计文档中的状态。 在下面,您可以查看当前数据库中的示例文档。

{
   "_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键,而是根据网址的状态进行计算。 我当前的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个URL

function(key, value, rereduce){ 
   return value.length;
}

替代文字http://img.skitch.com/20100316-qeawxgd5pru8d5i6bprygcsmhf.jpg

我究竟做错了什么? (我知道我想让您为我编写代码,但我感到内,但是现在我从数据库中获取数据后就进行了红宝石状态的计算。如果已经从数据库中获取了正确的数据,那就太好了。数据库)

reduce函数的变量value是map函数发出的值的数组。 在您的情况下, value是一个由“ url”数组组成的数组。 在蒲团中运行map-reduce时,它会设置group=true以便针对map函数发出的每个键分别运行map-reduce。 在您的情况下,这些键是文档_ids 也就是说,reduce函数的value是一个数组,其元素都是属于某个doc _id的所有url数组。 由于doc _id是唯一的,因此您最终得到reduce函数的value是一个包含一个元素的数组,该元素是相应doc的url数组。 这就是为什么value.length函数的value.length始终为1的原因。

但是,情况可能会变得更糟:如果您最终进入一个rereduce循环,则reduce函数的value是先前调用reduce函数所返回的value数组。 在您的情况下,您将使用看起来像["retrieved","new","retrieved"] value来调用reduce函数,这不会导致正确的结果。

通常,reduce函数用于聚合map函数发出的数据,例如对行进行计数或对值求和-在您的情况下这不是必需的。 您可以在此处阅读更多关于map-reduce的信息:

http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views

http://books.couchdb.org/relax/design-documents/views

doc.urls似乎是一个Object数组,其中包含status属性和url属性。 因此,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推动我寻求正确的解决方案,结果我真的不了解reduce函数。 我根本不需要reduce函数。

这是我为我解决的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);
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM