Slick 3.0 many-to-many query with the join as an iterable

回眸只為那壹抹淺笑 提交于 2019-12-03 13:26:02

So after reading this page and chatting on the mailing list, I finally got it working:

val eventInterestQuery = for {
  event <- EventQueries.query
  interest <- event.interests
} yield (event, interest)

Await.result(db.run(eventInterestQuery.result
  // convert the interests to a sequence.
  .map {
  _.groupBy(_._1)
    .map {
      case (k,v) => (k, v.map(_._2))
  }.toSeq
}
), Duration.Inf)

The only issue with groupBy is you lose order. You could fold the result. I've written this helper for my current project:

def foldOneToMany[A, B](in: Seq[(A, Option[B])], eq: (A, B) => Boolean)
                        (f: (A, B) => A): Seq[A] = 
  in.foldLeft(List.empty[A]) {
    case (head :: tail, (_, Some(rel))) if eq(head, rel) =>
      f(head, rel) :: tail
    case (r, (el, Some(rel))) => f(el, rel) :: r
    case (r, (el, None)) => el :: r
  }.reverse

It could do with some love. Now it takes in a function A,B => Boolean to determine if B belongs to A and a function A,B => A that adds B to A.

Virtualeyes also has a point. In Postgres you could use array_agg function to use a little less bandwidth from the db.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!