couchdb - 重新排序视图缩小的结果

时间:2012-01-09 22:58:01

标签: join couchdb reduce

考虑以下文档结构:

 - doc_type   1
 - _id        
 - subject    (string)

文章:

 - doc_type   2
 - _id        
 - thread_id  (_id of Thread)
 - time       (milliseconds since 1970)
 - comment    (string)

我需要按线程上的最后一篇文章排序的帖子,以及最新的5篇帖子。 我想避免在每次发布新帖子时更新线程文档,以消除跨db节点的分布式环境中发生冲突的可能性。此外,它将适用于数据库应该为您工作的数据库。

为简单起见,让我们先找到最新的帖子。 5个帖子可以采用相同的方式收集。

现在,我不确定我是否朝着正确的方向前进,看here我找到了如何使用使用组级返回线程的reduce函数在线程中查找最后一篇文章主题取自doc-type 1,最后一篇文档取自doc-type 2。

BTW - 反对链接中的示例,在我的情况下,总是使用第一个帖子创建一个线程(例如,Thread的创建日期将是它的第一个Post的日期)。

图:

function(doc){
  switch(doc.doc_type){
     case 1: emit([doc._id],doc); return;
     case 2: emit([doc.thread_id],doc); return;
  }
}

减少 对于真实世界的密钥更复杂,因此必须使用适当的组级别。 我也忽略了重新减少的情况,只是为了简单起见。 您可以找到完整图片here

function(keys, vals, rr){
   var result = { subject: null, lastPost: null, count :0 };
   //I'll ignore the re-reduce case for simplicity
   vals.forEach(function(doc){
      switch(doc.doc_type){
         case 1: 
            result.subject = doc.subject; 
            return;
         case 2: 
            if (result.lastPost.time < doc.time) result.lastPost = doc; 
            result.count++;
            return;
      }
   });
   return result;
}

但我如何页面后来按最新发布日期排序? 有没有办法从查询结果中提供doc-id作为另一个的过滤条件(最好是使用一次往返)?

一个帖子中的帖子数量没有限制,所以我有点不愿意在这里转发列表功能,当页面大小也可以变化时,会导致最后一个帖子根本没有显示...

任何人

1 个答案:

答案 0 :(得分:1)

如果您只是在最后一篇文章或最后五篇文章之后,那么有一种更简单的方法。事实上,你可以完全避免使用减速器。

如果您将时间添加为键的第二部分,则可以使用endkey,descending和limit的组合来根据thread_id获取最后N个帖子。

这是我用基于你的模式编写的一些测试数据写的MapReduce:

function(doc) {
  if (doc.type) {
    if (doc.subject) {
      emit([doc._id, doc.time], doc.subject);
      emit([doc._id, 'Z'], doc.subject);
    } else {
      emit([doc.thread_id, doc.time], {_id: doc._id});
    }
  }
}

“Z”键的奇怪输出是允许您从项目列表的“底部”获取主题。

查询参数类似于:

?endkey=["thread_id"]&descending=true&limit=6

限制应为N + 1,其中N是您想要回复的帖子数。在结果中,您将从帖子文档中获得主题主题和_id对象(或任何您喜欢的对象)。

在此示例中输出_id对象,因此如果您想要完整帖子,可以将其与include_docs=true一起使用。抛出您想要的帖子文档中的任何其他数据(标题等)以保持整体索引大小较低,并在需要文档全部内容的位置使用include_docs。但是,如果您始终需要完整的帖子文档,请将其输出到emit中,这样可以更快地响应(尽管磁盘上的索引大小更大)。

此外,如果您需要按最后一篇文章排序的所有主题的列表以及每个主题的5个帖子,您需要输出[time, thread_id, 'thread'][time, thread_id, 'post']等密钥并使用{{1收集每个线程文档“下”的帖子,因为时间排序会导致线程和帖子在结果中更远。然后可以使用_list函数再次组合/找到它们。但是,做两个请求可能仍然更容易/更轻。