从CouchDB视图获取具有最大字段值的文档列表

从CouchDB视图获取具有最大字段值的文档列表,couchdb,mapreduce,Couchdb,Mapreduce,假设我的CouchDB数据库中有这样的博客条目: {"name":"Mary", "postdate":"20110412", "subject":"this", "message":"blah"} {"name":"Joe", "postdate":"20110411", "subject":"that", "message":"yadda"} {"name":"Mary", "postdate":"20110411", "subject":"and this", "message":"bla

假设我的CouchDB数据库中有这样的博客条目:

{"name":"Mary", "postdate":"20110412", "subject":"this", "message":"blah"} {"name":"Joe", "postdate":"20110411", "subject":"that", "message":"yadda"} {"name":"Mary", "postdate":"20110411", "subject":"and this", "message":"blah-blah"} {"name":"Joe", "postdate":"20110410", "subject":"And other thing", "message":"yada-yada"} {"name":"Jane", "postdate":"20110409", "subject":"Serious stuff", "message":"Not really"} {“姓名”:“玛丽”,“发布日期”:“20110412”,“主题”:“此”,“消息”:“诸如此类”} {“姓名”:“乔”,“发布日期”:“20110411”,“主题”:“那个”,“消息”:“亚达”} {“姓名”:“玛丽”,“发布日期”:“20110411”,“主题”:“以及此”,“消息”:“诸如此类”} {“姓名”:“Joe”,“发布日期”:“20110410”,“主题”:“和其他东西”,“消息”:“yada yada”} {“姓名”:“简”,“发布日期”:“20110409”,“主题”:“严肃的东西”,“信息”:“不太”} 很容易得到所有帖子的列表。但是我如何从所有用户那里获得最新帖子的列表呢

就像这样:

{"name":"Mary", "postdate":"20110412", "subject":"this", "message":"blah"} {"name":"Joe", "postdate":"20110411", "subject":"that", "message":"yadda"} {"name":"Jane", "postdate":"20110409", "subject":"Serious stuff", "message":"Not really"} {“姓名”:“玛丽”,“发布日期”:“20110412”,“主题”:“此”,“消息”:“诸如此类”} {“姓名”:“乔”,“发布日期”:“20110411”,“主题”:“那个”,“消息”:“亚达”} {“姓名”:“简”,“发布日期”:“20110409”,“主题”:“严肃的东西”,“信息”:“不太”}
您将发出postdate作为键,因为键已排序。例如,这就是映射函数的外观

function(doc) {
  if(doc.postdate) {
    emit(doc.postdate, doc);
  }
}
这将为您提供按postdate升序排序的所有文档。如果您想要降序,则使用
?descending=true进行查询


干杯。

尝试使用此地图功能:

function(doc) {
  if (doc.postdate && doc.name) {
    emit([doc.name, doc.postdate], 1);
  }
}
function(keys, values, rereduce) {
  var max = 0,
      ks = rereduce ? values : keys;

  for (var i = 1, l = ks.length; i < l; ++i) {
    if (ks[max][0][1] < ks[i][0][1]) max = i;
  }
  return ks[max];
}
以及以下reduce函数:

function(doc) {
  if (doc.postdate && doc.name) {
    emit([doc.name, doc.postdate], 1);
  }
}
function(keys, values, rereduce) {
  var max = 0,
      ks = rereduce ? values : keys;

  for (var i = 1, l = ks.length; i < l; ++i) {
    if (ks[max][0][1] < ks[i][0][1]) max = i;
  }
  return ks[max];
}
函数(键、值、返回值){
var max=0,
ks=重新导出?值:键;
对于(变量i=1,l=ks.length;i
并使用
组\u level=1
进行查询。它为您提供了帖子的
\u id
,然后您可以使用单个查询检索所有帖子

我不确定这是否是最好的方法,但似乎有效


更新:修复了正确处理rereduce的映射。

不幸的是,这将包括(比如)玛丽的所有帖子,而我只查找最新的帖子。你对CouchDB的要求太高了吗?你可以做到,没问题!只需确保您正在降序并使用如下限制参数调用URL:
?descending=true&limit=1
。干杯。啊,我明白了:你想要每个用户的最新版本,而不是一般的最新版本。这只有通过多次调用和使用复杂键才能实现。例如,您的密钥结构将是
[doc.name,doc.postdate]
,然后您可以查询
?startkey=[“Mary”]&endkey=[“Mary”,{}]&descending=true&limit=1
,以获得Mary的最新帖子。谢谢你,山姆。我想这回答了我的问题。不幸的是,我不得不使用多个电话。当数据库中有将近一百万人时,这是不可行的。如果是这样的话,你可以自己在一个额外的文档中维护这个列表。给它一个“最新邮件”或类似的id。还可以看看couchdb lucene,了解更多更传统的查询功能。干杯,我试过这样的东西。这是我访问视图时得到的回报:“error”:“reduce\u overflow\u error”,“reason”:“减少输出必须更快地收缩:当前输出:。。。可能是因为我的文档实际上相当大,大约7-10K。我刚刚尝试加载30000个文档,它对我很有效。但是我只使用了四种不同的
doc.name
s。可能你有很多用户,但每个用户只有很少的帖子?您尝试过更新版本吗?请注意,我还将映射函数更新为
emit([doc.name,doc.postdate],1)
,而不是
emit([doc.name,doc.postdate],doc)