我有一个大型查询,似乎是streaming results的主要候选人。
我想调用一个函数,该函数返回一个对象,可以在其上应用其他映射转换,然后最终将整个结果转换为一个列表。这是因为转换将导致一组对象比数据库中的结果小得多,并且必须顺序进行许多不同的转换。一次处理每个结果将为我节省大量内存。
例如,如果数据库的结果是一个流(尽管正确的东西很可能是AkkaStream或Iteratee),那么我可以做类似的事情:
def outer(converter1[String, Int}, converter2[Int,Double]) {
val sqlIterator = getSqlIterator()
val mappedIterator1 = sqlIterator.map(x => converter1(x.bigColumn))
val mappedIterator2 = sqlIterator.map(x => converter2(x))
val retVal = mappedIterator.toList
retVal
}
def getSqlIterator() {
val selectedObjects = SQL( """SELECT * FROM table""").map { x =>
val id = x[Long]("id")
val tinyColumn = x[String]("tiny_column")
val bigColumn = x[String]("big_column")
NewObject(id, tinyColumn, bigColumn)
}
val transformed = UNKNOWN_FUNCTION(selectedObjects)
transformed
}
大多数文档似乎都提供了对结果应用“ reduce”功能而不是“ map”功能的机制,但是生成的映射功能将小得多,从而为我节省了大量内存。我应该为UNKNOWN_FUNCTION做些什么?
答案 0 :(得分:0)
下面是一个简单的示例,该示例使用Anorm的Akka Streams支持从类型为String
的单个列中读取值,对每个元素进行两次转换,然后将结果放入Seq
中。如果需要的话,我将保留它作为练习,让您一次从多个列中检索值。
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Sink
import anorm._
import scala.collection.immutable.Seq
import scala.concurrent.Future
implicit val system = ActorSystem("MySystem")
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher
val convertStringToInt: String => Int = ???
val convertIntToDouble: Int => Double = ???
val result: Future[Seq[Double]] =
AkkaStream.source(SQL"SELECT big_column FROM table", SqlParser.scalar[String])
.map(convertStringToInt)
.map(convertIntToDouble)
.runWith(Sink.seq[Double])