我有一个CouchDB数据库,其中包含以下类型的文档,表示建筑物内发生的事件:
{ person: 1
timestamp: 1
event: { type: enter
room: b }
}
和
{ person: 2
timestamp: 5
event: { type: leave
room: b }
}
我想解决的问题如下:我想知道其他每个人和第一个人在同一个房间里的总时间。请注意,任何人都可以在许多不同的时间进出许多房间。老实说,我不知道MapReduce是否是最好的范例,或者我是否应该导出我的数据并编写一个单独的脚本来解决这些问题(尽管这可能不是我们生产环境的可行解决方案)。
作为一个初始解决方案,我们假设所有数据都是正常的,因此进入房间的人稍后也会离开该房间。然而,在最终解决方案中,这一要求可能必须放宽,因为可能会遗漏一些事件。
我已经想到了一个潜在的解决方案,但我不知道这是否可能,也不知道如何在couchdb中做到这一点。这是一个大纲。
为每个进入房间事件的人创建一个发出以下格式的视图:
{ [room, person, timestamp], null }
创建一个每当人员1离开房间时都会发出
{ [room, timestamp], null}
的视图(可以是所有人的视图,但没有必要)。创建一个视图,对于除人员1以外的任何人员的每次退出房间事件,都执行以下操作。在映射步骤中:
- 查询第一个视图以查找该人员进入房间的最后时间戳
- 查询第一个视图以查找在退出房间事件之前人员1进入该房间的所有时间
- 对于这些时间中的每一个,都会查询第二个视图以查找该房间的所有退出时间,并针对每个间隔检查重叠的部分
- 将这些重叠相加并作为
{ person, time }
发射
减少:对每个人来说,把所有的时间加在一起。
然而,这取决于我是否能够弄清楚如何从视图中查询不同的视图。有人知道这是否可能吗?如果可能,怎么做?
我在CouchDB结构中找到的唯一方法是使用列表函数。我创建了一个视图,它只发出以[building,timestamp]为键的所有文档。这有助于我查询视图,以确保我有一天和一栋楼,带有startkey和endkey。
我现在创建了一个列表函数,它只接受视图返回的所有文档,并在javascript函数中执行处理。这在很大程度上绕过了map reduce框架,但这是我在CouchDB框架中想到的唯一方法。显然,使用CouchDB的RESTful API,任何其他脚本都可以完成同样的操作,而不是列表函数。