Couchdb map/reduce返回流中的第一个,然后按时间排序
我有一个couchdb,里面有一系列的活动。每个事件都有一个所有者、一个id、它发生的时间和一条消息(加上一堆与本练习无关的其他内容)。我想按时间顺序列出最近发生的事件。我仔细阅读了这个问题,并尝试使用它,在缩略器中进行比较,以保留第一条消息(使用我有一个复杂键的表单) 不幸的是,它似乎并没有达到你想要的效果 这是我的地图功能Couchdb map/reduce返回流中的第一个,然后按时间排序,couchdb,mapreduce,Couchdb,Mapreduce,我有一个couchdb,里面有一系列的活动。每个事件都有一个所有者、一个id、它发生的时间和一条消息(加上一堆与本练习无关的其他内容)。我想按时间顺序列出最近发生的事件。我仔细阅读了这个问题,并尝试使用它,在缩略器中进行比较,以保留第一条消息(使用我有一个复杂键的表单) 不幸的是,它似乎并没有达到你想要的效果 这是我的地图功能 function(doc) { var owner, id; if (doc.owner && doc.stream_id
function(doc) {
var owner, id;
if (doc.owner
&& doc.stream_id
&& doc.message
&& doc.receipt_time)
{
emit([doc.owner,doc.stream_id,doc.receipt_time],
{ owner: doc.owner,
stream_id: doc.stream_id,
timestamp: doc.receipt_time,
message: doc.message
});
}
}
还有我的reduce函数
function(keys, values) {
var challenger, winner = null;
for (var a = 0; a < values.length; a++) {
challenger = values[a];
if (! winner) {
winner = challenger;
} else {
if (winner.owner !== challenger.owner
&& winner.trace_id !== challenger.trace_id ) {
return null;
} else if (challenger.timestamp < winner.timestamp) {
winner = challenger;
}
}
}
return winner;
}
(请注意,最终条目实际上是最新的)
所以我希望最终的视图是现在的样子,但按时间排序。有什么方法可以做到这一点吗?如果我理解正确的话,您不需要筛选事件集合,而只需要对它们进行排序。假设这是正确的,解决方案实际上非常简单,甚至不需要reduce函数。映射函数中发出的键用于对视图进行排序,首先按键中的第一个键排序,然后按键中的其他键排序。换句话说,如果您想按流id排序,然后按接收时间排序,那么对emit的调用如下所示:
emit([doc.stream_id,doc.receipt_time,doc.owner], doc.message);
当然,如果您想按收据时间排序,然后按流id排序,则键应该是
[doc.receipt\u time,doc.stream\u id,doc.owner]
。我认为不需要在键中已经存在的值中包含任何内容,这就是为什么我将该值缩减为仅包含消息的原因。嗯,我认为最简单的方法实际上是避免该问题
因为我控制发送事件的软件,所以我刚刚在流中的第一个文档中添加了一个“start”:true,
字段,然后view函数只发送带有该值的事件
这意味着我无法获取历史数据,但这没关系,因为这主要用于检查最近的流
我尝试的另一种选择是添加一个list函数,它在一个键为[timestamp,owner,stream_id]的视图上发送每个所有者stream_id的第一个实例,但是,这会遇到一个问题,即当您限制时,它不会限制最终渲染的列表,而是限制原始视图,因此额外的键目前为止效果最好)
我仍然想知道是否有一些方法可以处理原始数据。在每条消息的时间戳处存储创建的流。因此,对于第一条消息,您使用当前时间。对于流中的每一条下一条消息,您都会从上一条消息复制它(创建一个视图,以获取流\u created\u at\u by\u stream\u id) 然后创建发出以下信息的视图:
[doc.owner,doc.stream_created_at, doc.stream_id, doc.receipt_time]
这将把来自同一个流的消息分组在一起,同时保持时间顺序。stream.id将确保在同时创建两个流时,来自不同流的消息不会混淆。接收时间将按时间对流中的消息进行排序
所以最终你会得到类似Facebook的对话。您根本不需要任何reduce函数。我想您是误解了。对于任何一个所有者+流id,最多可以有数千条消息。我想显示每个流中的第一条消息,然后按时间戳排序。如果您订购它们[owner,stream\u id,receive\u time],那么使用group\u level 2和我概述的reduce函数,我会按所有者和stream\u id获得每个流的第一条消息,但它们根据时间的顺序不正常。如果我将接收时间(即第三级组)包括在内,我会收到每一条信息,因此这与目的背道而驰。你是对的,我确实误解了。我认为可能还有一种更简单的方法可以做到,但我必须考虑一下。也许其中一位沙发专家会在这段时间来提供答案。
[doc.owner,doc.stream_created_at, doc.stream_id, doc.receipt_time]