2012-01-26 16 views
1

我已经在我的CouchDB的一份文件,其中的结构是这样的CouchDB减少:上的两个键

{date: 1234567, authors: ['Foo', 'Bar']} 

我的目标是要弄清楚某个作者如何“有效”。与以下做法很好。

map: function(doc) { 
    doc.authors.forEach(function(name) { 
    emit(name, 1); 
    }); 
}, 
reduce: function(keys, values) { 
    return sum(values); 
} 

但现在我不知道我怎么会能够也把一个(动态)限的日期:场?

干杯

回答

1

在重点放在date

地图:

function (doc) { 
    if (doc.authors && doc.date) { 
    doc.authors.forEach(function (author) { 
     emit([author, doc.date], 1); 
    }); 
    } 
} 

减少:

_sum 

和查询与(正确的URL编码):

startkey=['author',STARTDATE]&endkey=['author',ENDDATE]&group_level=1 

如果您希望多个作者使用单个查询,则不能使用reduce函数,因为reduce的结果大小不能取决于行数。以下是几种可能的解决方案:

  • 最常用的解决方案是使用list functions。但请记住,它们在服务器上很重,因为结果不会像map/reduce那样保存在磁盘上。

  • 如果您有预定义的时间段(例如月或年),则可以为doc.date所属的每个时间段发出一行,并将该时间段作为第一个元素放入密钥中。

例如使用下面的地图功能(同减少为前):

function (doc) { 
    if (doc.authors && doc.date) { 
    var periods = getPeriod(doc.date); 
    doc.authors.forEach(function (author) { 
     periods.forEach(function (period) { 
     emit([period, author], 1); 
     }); 
    }); 
    } 
} 

和查询有:

startkey=[PERIOD]&endkey=[PERIOD,{}]&group_level=exact 

这里getPeriod()是,你必须定义得到一个功能一个给定日期属于的期间数组。

+0

确实听起来很合理,但在这种情况下,我会减少到每个查询一个作者 - 对吗?所以我在这段时间内无法获得“所有”作者? – pagid

+0

你说过:«我的目标是弄清楚某个作者是如何“活跃”的。»这就是我所回答的。如果您希望所有作者使用单个查询,则不能使用reduce函数,因为它必须返回一个标量值(更确切地说,是一个小的固定大小值,不会随着结果行数的增加而增长)。添加了一些可能的解决方案。 –

+0

谢谢 - 添加期间是我的关键字 - 谢谢你推动我在正确的方向:) – pagid