具有一对多关系的灵活查询

Posted

技术标签:

【中文标题】具有一对多关系的灵活查询【英文标题】:Slick query with one to many relationship 【发布时间】:2018-10-25 14:27:13 【问题描述】:

我正在使用 slick 3.2.3,并且我正在尝试构建一个查询,该查询为两个具有一对多关系的实体返回 Seq[Entity1, Seq[Entity2]](每个 Entity1 关联多个 Entity2)。

所以我有我的两个实体

case class Entity1(name: String, id: Option[Long] = None)
case class Entity2(entity1Id: Long, name: String, id: Option[Long] = None

带有表定义(由 slick codegen 任务生成)

class entity1Table(_tableTag: Tag) extends profile.api.Table[Entity1](_tableTag, "ENTITY_1") 
   ...

lazy val groupTable = new TableQuery(tag => new groupTable(tag))

class entity2Table(_tableTag: Tag) extends profile.api.Table[Entity2](_tableTag, "ENTITY_2") 
   ...

lazy val entity2Table = new TableQuery(tag => new entity2Table(tag))

阅读this article 我已经创建了这样的查询

val q = (for 
  e1 <- entity1Table
  e2 <- entity2Table if e2.entity1Id === e1.id
 yield (e1, e2)).groupBy(_._1) map 
  case (entity1, tuples) => (entity1, tuples.map(_._2))


db.run(q.result)

但我在编译时收到此错误:

Error:(19, 35) No matching Shape found.
Slick does not know how to map the given types.
Possible causes: T in Table[T] does not match your * projection,
 you use an unsupported type in a Query (e.g. scala List),
 or you forgot to import a driver api into scope.
  Required level: slick.lifted.FlatShapeLevel
     Source type: (my.namespace.models.entity1Table, slick.lifted.Query[my.namespace.models.entity2Table,my.namespace.models.Entity2,[+A]Seq[A]])
   Unpacked type: T
     Packed type: G
     yield (e1, e2)).groupBy(_._1) map 

我怀疑它无法映射 entity1Table 和 entity2Table。

我该如何解决这个错误?

【问题讨论】:

【参考方案1】:

如Slick doc 中所述,groupBy 目前不支持执行具有Query 类型的嵌套值的查询:

中间查询(即查询以 groupBy() 结束,没有 聚合函数)包含查询类型的嵌套值。这些将 执行查询时变成嵌套集合,不是 目前支持。因此有必要将其压平 通过聚合它们的值(或单个 列)

换句话说,您的 Slick groupBy 查询必须与等效于 SQL 的 count()sum() 等的聚合函数结合使用。例如,等效于 select count(*) ... group by ... having count(*) &gt; 1 的以下查询将起作用:

val query = ( for 
    e1 <- entity1Table
    e2 <- entity2Table if e2.entity1Id === e1.id
   yield (e1, e2)
).
groupBy(_._1).map
  case (entity1, group) => (entity1, group.size)
.
filter(_._2 > 1)

【讨论】:

阅读文档似乎是对的,目前不支持我想要获取的内容。谢谢。

以上是关于具有一对多关系的灵活查询的主要内容,如果未能解决你的问题,请参考以下文章

jooq 具有一对多关系的单个查询

创建具有多个一对多关系的 DAO 查询?

减少 MySQL 中具有许多一对多关系 (ORM) 的查询

在 Mongoose 中,我有具有一对多关系的用户和角色模式。如何查询特定用户是不是具有“管理员”角色?

具有三层深度嵌套模型的查询集过滤器(多个一对多关系)

Doctrine 对一对多关系进行了许多查询