通过mongodb流媒体事件.获取最后插入的事件

Ph0*_*n1x 1 mongodb

我从现有数据库中消耗数据.这个数据库存储系统事件.我的服务应该通过计时器检查这个数据库,检查是否创建了一些新事件,然后上传并处理.像简单的队列实现.

问题是 - 每次检查数据库时,我怎样才能获得新的文档.我无法使用时间戳,因为事件从不同的源传递到数据库,并且没有任何事件顺序.所以我只需要使用插入顺序.

Rob*_*ore 5

有几种选择.

第一个,也是最简单的,如果它与您的用例匹配,是使用上限集合.上限集合是一个预定义大小的集合,充当一种环形缓冲区.一旦收集完毕,它就会开始覆盖文档.对于迭代集合,您只需创建一个"tailable"光标,您将需要一些方法来识别"处理的最后一个文档(即使文档中的一个简单的"完成"标志可以工作,但是在插入文档时它必须存在)如果您真的无法以任何方式修改文档,那么您甚至可以在某处保存最后处理的文档并使用课程时间戳(近似起始位置)并在处理更多文档之前查找最后一个文档.

此解决方案唯一真正的问题是,您可以在集合中编写的文档数量受到限制,并且不会随着时间的推移而增长.您可以对文档执行的写入操作有限制(它们不能增长),但听起来并不像是在修改文档.

第二个选项更复杂,就是使用oplog.对于独立配置,您仍需要传递-replSet选项以创建和使用oplog.您将不配置oplog.在分片配置中,您需要单独跟踪每个"副本集".oplog包含每个插入的文档,更新,删除服务器上的所有集合/文档.每个条目都包含一个时间戳,操作和id(至少).以下是各自的示例.

插入

{ "ts" : { "t" : 1362958492000, "i" : 1 }, 
  "h" : NumberLong("5915409566571821368"), "v" : 2, 
  "op" : "i", 
  "ns" : "test.test", 
  "o" : { "_id" : "513d189c8544eb2b5e000001" } }
Run Code Online (Sandbox Code Playgroud)

删除

{ ... "op" : "d", ..., "b" : true, 
   "o" : { "_id" : "513d189c8544eb2b5e000001" } }
Run Code Online (Sandbox Code Playgroud)

更新

{ ... "op" : "u", ..., 
  "o2" : { "_id" : "513d189c8544eb2b5e000001" }, 
  "o" : { "$set" : { "i" : 1 } } } 
Run Code Online (Sandbox Code Playgroud)

时间戳在服务器上生成,并保证单调增加.这使您可以快速找到感兴趣的文件.

此选项最强大,但您需要做一些工作.

我写了一些演示代码,在一个几乎你想要的集合上创建一个"观察者".你可以在GitHub上找到该代码.具体看一下com.allanbank.mongodb.demo.coordination包中的代码.

HTH,Rob