4

我想加入一个任意长度的过滤器列表or。如果列表是固定长度的,它将如下所示:

query.filter(filters(0) || filters(1) || … || filter(n))

加入过滤器and很容易:

for (filter ← filters)
    query = query.filter(filter)

Boolean将评估为s 的事物与 s 相连接or也很容易:

val any = evaluateToBools.foldLeft(true)(
    (left: Boolean, right: Eval2Bool) =>
    left || right.evaluate
)

更新:

正如我写的那样,如果 scalaqueryfilter是标准的,那将很容易。不幸的是,scalaquery 只允许这些过滤器由 sql 引擎执行。

所以我的具体问题是:如果我有一组字符串元组:

val tms = Set( ("A","a"), ("B", "b"), ... )

以及包含“t”和“m”两列的查询,

如何生成代表以下 SQL 的过滤器:

... WHERE/AND ( (t="A" and m="a") or (t="B" and m="b") or ... )

…或者可以将 sqlin运算符与这样的元组一起使用吗?

... WHERE (t,m) IN (("A","a"), ("B","b"), ...)

如果是这样,如何在scalaquery中做到这一点


黑客:

目前,我执行以下操作:

val tms = markers map { tm ⇒ tm._1 +"||"+ tm._2 }
query.filter(d ⇒ d._4 ++"||"++ d._5 inSet tms)

……但这太骇人听闻了。

解决方案

我这样实现了 Stefan 的解决方案:

rq = rq filter { d ⇒
    markers map { tm ⇒
        (d._4 is tm._1) && (d._5 is tm._2)
    } reduceLeft { _||_ }
}
4

2 回答 2

4

与组合谓词过滤 Scala 集合相比,这确实没有什么Query.filter不同。是的,它确实有一个更复杂的类型:

def filter[T](f: E => T)(implicit wt: CanBeQueryCondition[T]): Query[E, U] = ...

但是您可以放心地忽略CanBeQueryCondition类型类并假设TColumn[Boolean]Column[Option[Boolean]]只要您对所有谓词使用相同的类型(您总是可以这样做)。

那么你的filters序列类型是什么?我认为这就是您的问题所在。让我们从过滤 Scala 集合开始List[User]。这里谓词应该有类型User => Boolean,你可以减少应用的谓词||来组合它们:

case class User(id: Int, name: String)

val users = List(
  User(1, "foo"),
  User(2, "bar"),
  User(3, "blub")
)

val filters = List(
  { u: User => u.id == 1 },
  { u: User => u.name == "bar" }
)

val filtered = users filter { u =>
  filters map { _(u) } reduceLeft { _ || _ }
}

User现在我们为这些对象添加一个数据库表:

class DBUsers extends Table[User]("USERS") {
  def id = column[Int]("ID")
  def name = column[String]("NAME")
  def * = id ~ name <> (User, User.unapply _)
}
object DBUsers extends DBUsers

过滤 aQuery[DBUsers]需要类型的谓词DBUsers => Column[Boolean]

val dbFilters = List(
  { u: DBUsers => u.id === 1 },
  { u: DBUsers => u.name === "bar" }
)

组合和应用过滤器与之前完全相同:

val dbFiltered = DBUsers filter { u =>
  dbFilters map { _(u) } reduceLeft { _ || _ }
}

关于inSet元组的方法:我认为这是个好主意。请提交增强请求。一些数据库系统可以本机支持它,而对于其他数据库系统,可以使用此答案中概述的编码。

于 2011-08-28T13:04:47.640 回答
0

这个怎么样?

query.filter(filters reduceLeft (_ || _))
于 2011-06-29T16:09:00.817 回答