我正在尝试根据事件文档之间的时差将事件文档聚合到会话文档中:
我正在查看map-reduce和group& aggregate命令,但还没有提出让我这样做的解决方案。
条件:
文档结构:
Event = Schema({
start: Date,
end: Date,
})
Session = Schema({
start: Date,
end: Date,
duration: Number //will be an aggregate for the time of the events, ignoring the time in between
})
到目前为止最佳解决方案(非效率和非种族条件证明):
每个new_event = {start, finish}
的:
1. matched_events = Sessions.find{ start:{$lt:new_event.finish+20*60*1000},finish:{$gt:new_event.start-20*60*1000},
2. new_session = {start: $min:{matched_events.start}, finish: $max:{matched_events.finish}}
有什么想法吗?
答案 0 :(得分:1)
为了满足在将新数据添加到集合时实时响应的要求,您可以使用MongoDB复制oplog。 oplog记录每次写入数据库,通常用于允许副本集中的辅助节点跟随对主节点的写入,并将写入应用于辅助节点上的副本。但是,其他应用程序也可以使用它来监视数据库的更新。
要使用此功能,您需要将mongod设置为副本集,这将启用oplog录制。如果您不需要数据复制功能,则可以是单节点副本集。有关如何将独立mongod实例转换为单节点副本集的说明,请参阅this page。简而言之,您重新启动mongod指定--replSet选项,然后使用mongo shell连接并执行rs.initiate()。
完成此操作后,您现在有了一个oplog,它在“本地”数据库中显示为“oplog.rs”capped collection。一旦有了oplog,就可以创建一个tailable cursor来监控写操作。一个tailable游标在概念上类似于Unix tail -f命令:它接收添加到它正在监视的上限集合的每个文档的新结果。
在mongo shell中,它看起来像这样;其他语言驱动程序具有类似的功能:
tailable = DBQuery.Option.tailable + DBQuery.Option.awaitData
db.oplog.rs.find({}).addOption(tailable).forEach(function (d) {
print('--- op', d.op, 'ns', d.ns)
printjson(d.o)
// application logic goes here
})
每次发生写入时,您将获得一个新文档,其中包含详细说明写入的多个字段。你特别感兴趣的是
例如,前面的程序为每个插入的新文档打印以下内容:
--- op i ns test.c
{ "_id" : ObjectId("5310a0a0ca57fb03897318f8"), "hello" : "world" }
然后,您将在此循环中添加所需的聚合逻辑,检查插入的对象以确定如何将其与先前的文档聚合,从而可能将聚合的文档插入到db中。
您可以在find()中指定查询字词,以确保您只能看到感兴趣的事件。例如,此版本只允许您在“test”数据库的“c”集合上插入:
tailable = DBQuery.Option.tailable + DBQuery.Option.awaitData
db.oplog.rs.find({op:'i', ns:'test.c'}).addOption(tailable).forEach(function (d) {
// application logic goes here
})
这有帮助吗?还有什么需要进一步澄清的吗?