关于mongodb:批量插入/使用Play Framework,ReactiveMongo插入多个对象

Bulk insert / Insert many with Play Framework, ReactiveMongo

我正在使用Play Framework 2.5.0和ReactiveMongo构建应用程序,我花了很多时间在某些事情上,而这些事情在大多数网络语言中都非常容易做到。

那东西一次插入许多文档。
为此,我必须使用ReactiveMongo函数bulkInsert

我发现这个Google网上论坛有一个非常简单的示例,但是从2013年开始,现在签名已更改

1
def bulkInsert[T](enumerator: Enumerator[T])

1
def bulkInsert(documents: Stream[P.Document], ordered: Boolean, writeConcern: WriteConcern)(implicit ec: ExecutionContext): Future[MultiBulkWriteResult]

因此,在这里我尝试以该示例为例,并找到一种将Enumerator转换为Stream的方法(找不到任何方法):

1
2
3
4
5
6
7
8
9
10
11
12
val schemasDocs: Seq[JsObject] = {
  jsonSchemas.fields.map {
    case (field, value) => Json.obj(field -> value)
  }
}
val enumerator = Enumerator.enumerate(schemasDocs)
val schemasStream = Source.fromPublisher(Streams.enumeratorToPublisher(enumerator)) // my attempt to turn enumerator into a Stream
val schemasInsert = {
  getCollection("schemas").flatMap(
    _.bulkInsert(schemasStream, true)
  )
}

现在,我发现自己沉迷于Akka,ReactiveMongo和Play API中,尝试从JsObjects的Seq创建一个JsObjects流。

然后,我尝试了另一种方法:ReactiveMongo网站上的示例

1
2
val bulkDocs = schemasDocs.map(implicitly[collection.ImplicitlyDocumentProducer](_))
collection.bulkInsert(ordered=true)(bulkDocs: _*)

给了我一个很难调试的错误:

1
type mismatch; found : Seq[reactivemongo.play.json.collection.JSONCollection#ImplicitlyDocumentProducer] required: Seq[x$48.ImplicitlyDocumentProducer]

我宁愿不使用Streams也不使用第二种解决方案,因为我不希望代码中包含我不了解的内容。


我刚刚发现了如何处理bulkInsert。 有一个例子

build.sbt

1
2
3
4
5
...
libraryDependencies ++= Seq(
 "org.reactivemongo" %%"play2-reactivemongo" %"0.11.14"
)
...

plugins.sbt

1
addSbtPlugin("com.typesafe.play" %"sbt-plugin" %"2.5.12")

CxTransactionsRepository.scala

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package cx.repository

import cx.model.CxTransactionEntity
import play.modules.reactivemongo.ReactiveMongoApi
import reactivemongo.play.json.collection.JSONCollection

import scala.concurrent.{ExecutionContext, Future}

class CxTransactionsRepository @Inject()(val reactiveMongoApi: ReactiveMongoApi)(implicit ec: ExecutionContext){

  private val cxTransactionsCollectionFuture: Future[JSONCollection] = reactiveMongoApi.database.map(_.collection[JSONCollection]("cxTransactions"))

  def bulkInsert(seq: Seq[CxTransactionEntity]): Future[Int] = {
    for {
      transactions <- cxTransactionsCollectionFuture
      writeResult <- transactions.bulkInsert(ordered = false)(seq.map(implicitly[transactions.ImplicitlyDocumentProducer](_)): _*)
    } yield {
      writeResult.n
    }
  }

}