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

Scala Slick 3.3.x如何将两个filterOpt合并为OR条件查询?

问题:合并Slick的filterOpt实现OR逻辑查询条件

我在Scala中定义了两个可选字符串序列:

val firstSeq = Some(Seq("1", "2", "3"))
val secondSeq = Some(Seq("car", "dog", "cat"))

目前我使用Slick查询Oracle数据库,代码如下:

(for {
  number <- numbers
    .filterOpt(firstSeq)((table, gs) => table.count.inSetBind(gs) && table.type === NumberType.Numeric)
    .filterOpt(secondSeq)((table, rs) => table.count.inSetBind(rs) && table.type === NumberType.String)
} yield {
  number
}).result

请问是否有办法将这两个filterOpt方法合并为一个,实现OR逻辑的查询条件?


解决方案

当然可以,核心思路是将两个可选序列对应的条件组合成一个可选的复合OR条件,再通过一次filterOpt应用到查询上,避免多次链式调用。

模式匹配实现(清晰直观)

通过模式匹配处理两个Option的所有组合情况,生成对应的复合条件:

// 定义复合可选条件
val combinedCondition = (firstSeq, secondSeq) match {
  case (Some(gs), Some(rs)) =>
    Some((table: NumberTable) => 
      (table.count.inSetBind(gs) && table.type === NumberType.Numeric) || 
      (table.count.inSetBind(rs) && table.type === NumberType.String)
    )
  case (Some(gs), None) =>
    Some((table: NumberTable) => table.count.inSetBind(gs) && table.type === NumberType.Numeric)
  case (None, Some(rs)) =>
    Some((table: NumberTable) => table.count.inSetBind(rs) && table.type === NumberType.String)
  case (None, None) => None
}

// 应用复合条件到查询
numbers.filterOpt(combinedCondition)(_ apply _).result

简化写法(利用Option操作符)

如果觉得模式匹配冗余,可以先把每个序列转换成对应的可选条件,再组合成OR逻辑:

// 先将每个可选序列转为可选条件
val firstCondition = firstSeq.map(gs => 
  (table: NumberTable) => table.count.inSetBind(gs) && table.type === NumberType.Numeric
)
val secondCondition = secondSeq.map(rs => 
  (table: NumberTable) => table.count.inSetBind(rs) && table.type === NumberType.String
)

// 组合两个可选条件为OR逻辑
val combinedCondition = (firstCondition, secondCondition) match {
  case (Some(c1), Some(c2)) => Some(c1 || c2)
  case (existing @ Some(_), None) => existing
  case (None, existing @ Some(_)) => existing
  case _ => None
}

// 执行查询
numbers.filterOpt(combinedCondition)(_ apply _).result

逻辑说明

  • 当两个序列都存在时,生成(条件1) || (条件2)的复合过滤逻辑;
  • 仅单个序列存在时,直接使用该序列对应的过滤条件;
  • 两个序列都不存在时,不添加任何过滤条件,返回全量数据。

这样既实现了OR逻辑的合并,又保留了filterOpt原本的可选过滤特性,代码结构更简洁。


内容的提问来源于stack exchange,提问作者M. Barabas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:08:24