You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slick如何对左连接查询得到的Option类型字段执行排序操作

问题原因

左连接操作返回的右表数据是Option类型,当父评论没有关联的子评论时,childComments为None,你代码中未对replyCount做空值兜底处理,因此最终计算得到的hot(即row._4)为Option[Int]类型,无法直接执行排序操作,强行调用.get还会在空值场景下抛出异常。

最优解决方法

在map阶段就将所有Option类型的业务字段转换为非Option类型,业务上无对应子评论时回复数、子评论点赞总和默认取0即可,从根源避免Option排序的问题:

val query =
  Tbcomments
    .joinLeft(getChildCommentStatQuery)
    .on(_.iid == _._1)
    .filter { case (comments, _) =>
      comments.itargetid === commentTargetId && comments.iparentid === 0 && comments.istatus === statusNormal
    }
    .map { case (comments, childComments) =>
      // 无子评论时回复数默认为0,转成非Option类型
      val replyCount = childComments.map(_._2).getOrElse(0)
      // 修正原有写法的小问题:childComments本身是Option,先flatMap再取默认值更稳妥
      val childLikeSum = childComments.flatMap(_._3).getOrElse(0)
      val likeCountSum = comments.ilikecount + childLikeSum
      // 现在hot是普通Int类型,不再是Option
      val hot = replyCount + likeCountSum
      val support = comments.ilikecount - comments.inotlikecount
      (comments.iid, replyCount, likeCountSum, hot, support, comments.dtcreated)
    }
    .sortBy(row =>
      sortOrder match {
        case LATEST_COMMENT_ORDER   => row._6.desc
        case EARLIEST_COMMENT_ORDER => row._6.asc
        case SUPPORT_COMMENT_ORDER  => row._5.desc
        case HEAT_COMMENT_ORDER     => row._4.desc
      })

备选方案(保留Option字段的场景)

如果你有特殊业务需要保留hot为Option类型,可以在排序时指定空值的排序规则:

// 空值热度按0计算排在末尾
case HEAT_COMMENT_ORDER     => row._4.getOrElse(0).desc
// 或者用Slick原生的空值排序语法,None值统一放在最前/最后
case HEAT_COMMENT_ORDER     => row._4.desc.nullsLast

内容的提问来源于stack exchange,提问作者BugSource

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 22:45:01