Slick 3.0.0:如何查询一对多/多对多关系

Posted

技术标签:

【中文标题】Slick 3.0.0:如何查询一对多/多对多关系【英文标题】:Slick 3.0.0: How to query one-to-many / many-to-many relations 【发布时间】:2015-08-14 13:12:49 【问题描述】:

大约一年前,对于 slick 2.x (scala slick one-to-many collections),基本上也有人问过同样的问题。我想知道反应性光滑的发布是否有任何进展。

假设我们有三个表。 librarybooklibrary_to_book 图书馆有很多书。我想要的是一个图书馆的清单,里面有他们的书。在 Scala 中,这类似于Seq[(Library, Seq[Book])]。我的查询如下:

val q = (for 
  l   <- libraries
  ltb <- libraryToBooks if l.id === ltb.libraryId
  b   <- books if ltb.bookId === b.id
 yield (l, b)
db.run(q.result).map( result => ??? )

results 在这种情况下是Seq[(Library, Book)] 类型。我如何更改我的查询以获得Seq[(Library, Seq[Book])] 类型的结果?编写此类查询的“巧妙方式”是什么?

【问题讨论】:

【参考方案1】:

IMO 您的代码看起来不错。这真的取决于你觉得什么更具可读性。或者,您也可以使用 join

val findBooksQuery = libraries
  .join(libraryToBooks).on(_.id === _.libraryId)
  .join(books).on(_.id === _._2.bookId)
  .result

val action = (for 
  booksResult <- findBooksQuery
 yield 
  booksResult.map  row =>
    val (libraryTableRow, libraryToBooksTableRow) = row._1
    val booksTableRow = row._2
    // TODO: Access all data from the rows and construct desired DS
  


db.run(action)

然后,您可以对特定键执行 groupBy 以获得您正在寻找的数据结构。在这种情况下,它会更加进化,因为它是跨三个表连接的。例如,将以下内容添加到您的查询中:

val findBooksQuery = libraries
  .join(libraryToBooks).on(_.id === _.libraryId)
  .join(books).on(_.id === _._2.bookId)
  // To group by libraries.id
  .groupBy(_._1.id)
  .result

【讨论】:

正如 Sky 之前在评论中提到的,在光滑的 atm 中没有办法做到这一点。我想你提出的.groupBy 方法是目前的方法。 @Roman 如果图书馆没有书,这会返回一个空的Seq 吗?如果是这样,它可能与预期不太相符。 @acjay:在这种情况下,这确实会导致一个空的Seq。如果您想在结果中包含所有图书馆,无论它们是否有书籍,您都可以使用外连接而不是内连接(joinLeftjoinRight 用巧妙的术语)。如果这不是您想要的,请随时提出后续问题:) @Roman 我 认为 我已经弄清楚了我的情况(与您的问题类似)。我使用joinLeft,然后在运行查询后,我正在执行.groupBy(_._1).mapValues(_.flatMap(_._2)).toSeq 以到达Seq[(OneTable, Seq[ManyTable])] @acjay 很高兴听到。竖起大拇指!【参考方案2】:

对于您想要映射到的内容,db.run 在您的情况下返回 Future(of something)、Future[Seq[(Library, Seq[Book])]]。映射未来时,您可以访问 Seq,并且可以将其转换为其他东西以获得新的未来。

【讨论】:

感谢您的回答。不幸的是,这不是我想要的。我刚刚更新了我的问题并试图更具体一点。

以上是关于Slick 3.0.0:如何查询一对多/多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

CoreData:查询一对多对多的关系

gorm 关系一对一,一对多,多对多查询

核心数据:NSPredicate 一对多对多关系

如何利用 Prisma 的隐式关系来创建以下关系? (一对多,多对多,一对一)

gorm 关系一对一,一对多,多对多查询

gorm 关系一对一,一对多,多对多查询