【问题标题】:Slick 3: count "OR NULL" with leftJoin and groupBySlick 3:用 leftJoin 和 groupBy 计算“OR NULL”
【发布时间】:2018-01-09 02:22:09
【问题描述】:

我正在创建一个微博系统。像 Twitter 一样,我想用“(1) Like Count”和“(2) 用户是否已经喜欢它?”来检索帖子数据。

我的数据库架构:
帖子(id:Int,标题:String)
最喜欢的(id: Int, post_id: Int, user_id: Int)

我可以在 SQL 中得到我想要的(假设用户的 id 是 1)。

SELECT post.id, post.title, COUNT(favorite.id), COUNT(favorite.user_id = 1 OR NULL) FROM post 
  LEFT JOIN favorite ON post.id = favorite.post_id
  GROUP BY post.id

但是对于 Slick 3,我不知道如何在 (2) 上获得相同的结果。

Post.joinLeft(Fav).on(_.id  === _.postId)
    .groupBy(_._1)
    .map { case (post, group) => (
        post,
        group.map(_._2.map(_.id)).countDefined,  // (1) this works!
        group.map(_._2.???).countDefined   // (2) ?
    )}

如何查询?

更新: Fav 列的 Slick Schema(我使用了 slick-codegen)

val id: Rep[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
val userId: Rep[Int] = column[Int]("user_id")
val postId: Rep[Int] = column[Int]("post_id")

【问题讨论】:

  • Favourite 的精巧架构是什么?
  • 感谢您的评论。我已经更新了我的帖子。我从中提取了列定义(我认为这是您想知道的),但是如果您愿意,我可以粘贴 Fav 的所有架构。

标签: scala slick slick-3.0


【解决方案1】:

您可以通过更改以下行从 Sarvesh Kumar Singh 的答案中删除编译错误(但在 slick 3.1.X 和 3.2.X 上会出现运行时错误):

group.filter{
      case (p, f) => f.filter(_.userId === 1).isDefined
    }.length

由于 f 的类型是 Rep[Option[Favorite]],因此您没有直接可用的 f.userId。

注意:当您尝试在 groupBy + filter 或 map 之后调用 length 函数时,该 slick 会引发运行时错误。您可以在此处跟踪问题 - https://github.com/slick/slick/issues/1355

您可以改用以下代码:

Post.joinLeft(Favorite)
  .on(_.id  === _.postId)
  .groupBy(_._1)
  .map{ case (post, group) => (
    post,
    group.map(_._2.map(_.id)).countDefined,
    group.map(_._2.filter(_.userId === 1).map(_.userId)).countDefined 
    )}

【讨论】:

    【解决方案2】:

    我不太确定这是否可行,但我记得之前做过类似的事情。

    你现在可以试试这个(假设favourite.user_idColumn[Option[Int]]),

    Post.joinLeft(Fav)
      .on(_.id  === _.postId)
      .groupBy(_._1)
      .map({ case (post, group) => (
        post,
        group.map(_._2.map(_.id)).countDefined,
        group.filter({
          case (p, f) => f.user_id.isEmpty || f.user_id.filter(_ == 1).isDefined
        }).length
      )})
    

    【讨论】:

    • 感谢您的回答!但是,我在f.user_id 遇到编译错误。我认为f 是某种列表,所以也许它必须被折叠(或减少)以获得布尔值。我在Rep[Option[T]]找不到这样的功能,所以不知道怎么实现这个...
    • value userId is not a member of slick.lifted.Rep[Option[models.Tables.Fav]] f.userIdambiguous implicit values: both value BooleanOptionColumnCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[slick.lifted.Rep[Option[Boolean]]] and value BooleanCanBeQueryCondition in object CanBeQueryCondition of type => slick.lifted.CanBeQueryCondition[Boolean] match expected type slick.lifted.CanBeQueryCondition[Nothing] group.filter({
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    相关资源
    最近更新 更多