【问题标题】:ReactiveMongo + Play 2: stream a sub document (array)ReactiveMongo + Play 2:流式传输子文档(数组)
【发布时间】:2015-09-18 12:25:33
【问题描述】:

在下面的例子中,我使用的是:

  • MongoDB(> 3.0,带有 WiredTiger 引擎)
  • 在 Scala 中播放框架 2.3.8
  • org.reactivemongo:play2-reactivemongo:0.11.0.play23-M3

首先,假设我们在名为“urlColl”的 MongoDB 集合中有以下文档:

{
  "_id" : ObjectId("5593bebe89645672000deec4"),
  "url" : "urlPath",
  "content" : [
      "a",
      "ab",
      "abc",
      "abcd"
  ]}

在 Play 中,只要将新文档插入“urlColl”集合,就可以将新文档流式传输到客户端,在 Play 中使用以下方法:

def feed = Action {
  val cursor = collection
    .find(BSONDocument(), BSONDocument("content" -> 1))
    .options(QueryOpts().tailable.awaitData)
    .cursor[List[Try[BSONValue]]](ReadPreference.nearest)

  val dataProducer = cursor.enumerate(Int.MaxValue).map(_.toString)
  Ok.chunked(dataProducer &> EventSource()).as("text/event-stream")
}

和隐式阅读器:

implicit object ContentToList extends BSONDocumentReader[List[Try[BSONValue]]] {
    def read(doc: BSONDocument): List[Try[BSONValue]] = {
      doc.getAs[BSONArray]("content").get.stream.toList
    }
}

然后,每次插入带有“内容”数组的新文档时,都会自动发送给客户端。

我的问题很简单:

是否可以将注入“内容”子数组中的新数据流式传输到客户端?

确实,由于没有插入新文档(在现有文档的数组中插入了新值),因此在游标中没有检测到任何内容,更何况没有向客户端发送任何内容。

提前谢谢你!


@cchantep,回答您的最后一条评论:

是的,我遇到了一些缓慢的查询。事实上,我在一个网页中有一个表单用于推送数据,另一个网页用于服务器发送事件。

验证第一页的表单最多可能需要 3 秒。 在 Mongo 日志中,我可以看到:

I QUERY    [conn329] getmore test.events cursorid:22982535122 ntoreturn:0 
keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:86 
locks:{ Global: { acquireCount: { r: 1000 } }, Database: { acquireCount: 
{ r: 1000 } }, Collection: { acquireCount: { r: 1000 } } } 2783ms. 

这是由于可尾游标而导致的事件集合 (2783ms) 的日志。也许这会导致问题?

编辑: 我禁用了可尾游标 (coll.find(selector).options(QueryOpts().tailable.awaitData)) 并且性能要好得多。你有什么想法吗?

谢谢!

【问题讨论】:

    标签: mongodb scala stream playframework-2.3 reactivemongo


    【解决方案1】:

    最终的release of 0.11.0"org.reactivemongo" %% "play2-reactivemongo" % "0.11.0.play23"

    关于子数组,MongoDB 中的可尾游标(不仅是 ReactiveMongo)正在监视新的顶级文档。由于您的文档已更新以将元素添加到数组属性中,因此它在创建时已在游标流中返回。

    如果要实现事件源,最好将可尾光标放在事件集合上而不是实体集合(快照集合)上。

    您可以找到使用 EventSourcePlay Mongo Knockout 的示例 Play 应用。

    【讨论】:

    • 感谢@cchantep 的及时答复!我将尝试您的解决方案,并会及时通知您。此外,对于使用 Akka 作为该用例的可尾光标的替代品,您是否有任何信息/链接/意见?
    • ReactiveMongo 在底层使用 Akka 来实现响应式结果,所以如果你能适应事件溯源方法,我认为你不必管理自定义 Actor 系统。
    • 因此,这是从 MongoDB 流式传输文档的最佳解决方案吗?使用可尾光标,这种解决方案的性能似乎(还没有?)非常好。谢谢!
    • 我有几个使用可尾光标部署的项目。您现在是否遇到性能问题?
    • 我已经做出了回答继续讨论,有更多的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 2017-10-31
    • 2015-10-21
    相关资源
    最近更新 更多