我正在使用reactivemongo-akka-stream并尝试转换AkkaStreamCursor.documentSource
。我正在看到两个问题:
documentation表示此操作返回Source[T, NotUsed]
但collection.find(query).cursor[BSONDocument].doccumentSource()
返回Source[BSONDocument, Future[State]]
。有没有办法避免State对象?
假设我使用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))))
但是我没有找回我可以处理的Future[Source[Outer, Future[State]]
,而是返回Future[Source[Inner, Future[State]]#Repr[Outer]]
如何将bson读者与此库一起使用?
答案 0 :(得分:0)
根据cchantep的建议,我需要将fromFuture
与flatMapConcat
一起使用:
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)
}