2

我正在为使用 ReactiveMongo 的 MongoDB 编写 DAO Actor。我想实现一些非常简单的 CRUD 操作,其中包括一次 upsert 多条记录的能力。由于我有一个反应式应用程序(基于 Akka 构建),因此具有幂等操作对我来说很重要,因此我需要该操作是 upsert,而不是 insert。

到目前为止,我有以下(丑陋的)代码可以做到这一点:

case class UpsertResult[T](nUpd: Int, nIns: Int, failed: List[T])

def upsertMany[T](l: List[T], collection: BSONCollection)
  (implicit ec: ExecutionContext, w: BSONDocumentWriter[T]):
    Future[UpsertResult[T]] = {
      Future.sequence(l.map(o => collection.save(o).map(r => (o, r))))
        .transform({
          results =>      
            val failed: List[T] = results.filter(!_._2.ok).unzip._1
            val nUpd = results.count(_._2.updatedExisting)
            UpsertResult(nUpd, results.size - nUpd - failed.size, failed)
        }, t => t)
      }    

是否有一种开箱即用的方法可以单独使用 reactivemongo API 一次更新许多记录?

我是 MongoDB 初学者,所以这对许多人来说可能听起来微不足道。任何帮助表示赞赏!

4

2 回答 2

3

Mongo 不支持在一个查询中插入多个文档。例如更新操作总是只能插入一个新元素。所以这不是 reactivemongo 驱动程序的缺陷,根本没有 DB 命令可以达到您期望的结果。迭代您要更新插入的文档是正确的方法。

关于 upsert 的 mongodb 手册包含更多信息:

http://docs.mongodb.org/manual/core/update/#update-operations-with-the-upsert-flag

于 2013-12-10T20:22:33.013 回答
0

根据文档,BSSONCollection.save inserts the document, or updates it if it already exists in the collection请参见此处。现在,我不确定它是如何决定文档是否已经存在的:大概它是基于 MongoDB 告诉它的......所以主键/id 或唯一索引。

简而言之:我认为你的做法是正确的(包括你的结果从LastError)。

于 2013-12-10T18:01:57.600 回答