与Quill一起加入多对多组合

时间:2017-12-18 08:51:04

标签: postgresql scala quill.io

我试图用Quill实现以下PostgreSQL查询的功能:

select books.*, array_agg(authors.name) from books 
join authors_books on(books.id = authors_books.book_id)
join authors on(authors.id = authors_books.author_id)
group by books.id

现在我的Quill版本中有这个:

val books = quote(querySchema[Book]("books"))
val authorsBooks = quote(querySchema[AuthorBook]("authors_books"))
val authors = quote(querySchema[Author]("authors"))

val q: db.Quoted[db.Query[(db.Query[Book], Seq[String])]] = quote{
        books
            .join(authorsBooks).on(_.id == _.book_id)
            .join(authors).on(_._2.author_id == _.id)
            .groupBy(_._1._1.id)
            .map {
                case (bId, q) => {
                    (q.map(_._1._1), unquote(q.map(_._2.name).arrayAgg))
                }
            }
    }

如何摆脱结果中的嵌套查询(db.Query [Book])并获取Book?

1 个答案:

答案 0 :(得分:1)

我可能对SQL有点生疏,但你确定你的查询是有效的吗?特别是我发现你在import { Component } from '@angular/core'; import { IonicPage, NavController, NavParams } from 'ionic-angular'; @IonicPage() @Component({ selector: 'page-verify-number', templateUrl: 'verify-number.html', }) export class VerifyNumberPage { container: number; constructor(public navCtrl: NavController, public navParams: NavParams) { } onPoping(){ this.navCtrl.pop(); } } select books.* group by books.id时表示怀疑,即你直接返回你没有分组的字段。并尝试直接翻译错误的查询是导致出错的原因

解决此问题的一种方法是按所有字段执行group by。假设Book被声明为:

case class Book(id: Int, name: String)

你可以做到

  val qq: db.Quoted[db.Query[((Index, String), Seq[String])]] = quote {
    books
      .join(authorsBooks).on(_.id == _.book_id)
      .join(authors).on(_._2.author_id == _.id)
      .groupBy(r => (r._1._1.id, r._1._1.name))
      .map {
        case (bId, q) => {
          // (Book.tupled(bId), unquote(q.map(_._2.name).arrayAgg)) // doesn't work
          (bId, unquote(q.map(_._2.name).arrayAgg))
        }
      }
  }

  val res = db.run(qq).map(r => (Book.tupled(r._1), r._2))

不幸的是,您似乎无法在Book.tupled内应用quote因为您收到错误

  

monad组合物不能使用应用连接来表达

但您可以在db.run致电后轻松完成,以便取回Book

另一种选择是仅按Book.id进行分组,然后再次加入Book表以获取所有字段。如果Book

中有许多字段,这可能实际上更清晰,更快