我有mongodb查询结果的迭代器,我想将这些结果流式传输到http响应,而不将整个结果集加载到内存中。
是否可以使用迭代器而不是集合或未来完成akka http响应?
答案 0 :(得分:2)
给出Iterator
数据:
type Data = ???
val dataIterator : () => Iterator[Data] = ???
您首先需要一个功能来将Data
转换为ByteString
表示形式,以及表示形式的ContentType
(e.g. json, binary, csv, xml, ...):
import akka.util.ByteString
import akka.http.scaladsl.model.ContentType
val dataToByteStr : Data => ByteString = ???
//see akka.http.scaladsl.model.ContentTypes for possible values
val contentType : ContentType = ???
现在可以使用Iterator和转换器函数创建一个HttpResponse,它将结果流回http客户端,而不会将整个数据集保存在内存中:
import akka.http.scaladsl.model.HttpEntity.{Chunked, ChunkStreamPart}
import akka.http.scaladsl.model.ResponseEntity
import akka.stream.scaladsl.Source
import akka.http.scaladsl.model.HttpResponse
val chunks : Source[ChunkStreamPart,_] =
Source.fromIterator(dataIterator)
.map(dataToByteStr)
.map(ChunkStreamPart.apply)
val entity : ResponseEntity = Chunked.fromData(contentType, chunks)
val httpResponse : HttpResponse = HttpResponse(entity=entity)
注意:由于每次从dataIterator
生成一个新的迭代器,您不必为每个传入请求创建新的httpResponse
;所有请求都可以使用相同的响应。
答案 1 :(得分:0)
看看Alpakka MongoDB connector。它允许从Mongo集合创建一个Source,如:
val source: Source[Document, NotUsed] = MongoSource(numbersColl.find())
val rows: Future[Seq[Document]] = source.runWith(Sink.seq)
或者您可能希望将自己的源实现作为GraphStage。