ReactiveMongo与Akka Streams自定义来源

时间:2017-06-24 07:19:51

标签: scala akka-stream reactivemongo

我正在使用reactivemongo-akka-stream并尝试转换AkkaStreamCursor.documentSource。我正在看到两个问题:

  1. documentation表示此操作返回Source[T, NotUsed]collection.find(query).cursor[BSONDocument].doccumentSource()返回Source[BSONDocument, Future[State]]。有没有办法避免State对象?

  2. 假设我使用Future[State]我希望得到以下类的来源

    case class Inner(foo: String, baz: Int)
    
    case class Outer(bar: Inner)
    
    //
    implicit object InnerReader extends BSONDocumentReader[Inner]//defined
    
    val getCollection: Future[BSONCollection] = connection.database("db").map(_.collection("things")
    
    def stream()(implicit m: Materializer): Source[Outer, Future[State]] = {
     getCollection.map(_.find().cursor[Inner]().documentSource()).map(_.via(Flow[Inner].map(in => Outer(in))))
    
  3. 但是我没有找回我可以处理的Future[Source[Outer, Future[State]],而是返回Future[Source[Inner, Future[State]]#Repr[Outer]]

    如何将bson读者与此库一起使用?

1 个答案:

答案 0 :(得分:0)

根据cchantep的建议,我需要将fromFutureflatMapConcat一起使用:

def stream()(implicit m: Materializer): Source[Outer, NotUsed] = {
 val foo = getCollection.map(x => col2Source(x))

 fix(foo).via(flowmap(map = Outer(_)))
}
def col2Source(col: BSONCollection): Source[Inner, Future[State]] = {
 val cursor: AkkaStreamCursor[Inner] = 
   col.find(BSONDocument.empty).cursor[Inner]()

 cursor.documentSource()
}

def flowmap[In, Out](
 map: (In) => Out
): Flow[In, Out, NotUsed] = Flow[In].map(e => map(e))

def fix[Out, Mat](futureSource: Future[Source[Out, Mat]]): Source[Out, NotUsed] = {
 Source.fromFuture(futureSource).flatMapConcat(identity)
}