4

フィルタの任意の長さのリストを で結合したいor。リストが固定長の場合、次のようになります。

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

フィルターを結合するのandは簡単です:

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

Booleans と評価されるものを結合するのorも簡単です:

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

アップデート:

filter私が書いたように、scalaqueryが標準的なものであれば簡単です。残念ながら、scalaquery では、SQL エンジンによるこれらのフィルターの実行しか許可されていません。

だから私の具体的な質問は次のようになります: 文字列タプルのセットがある場合:

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

2 つの列「t」と「m」を含むクエリ、

次の SQL を表すフィルターを生成するにはどうすればよいですか?

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

in…または、このようなタプルでSQL 演算子を使用できますか?

... 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)

…しかし、それは耐え難いハックです。

解決

私はステファンのソリューションを次のように実装しました:

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

2 に答える 2

4

Query.filterScala コレクションをフィルター処理するために述語を組み合わせることと、これが何の違いもありません。はい、もっと複雑な型があります:

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

ただし、型クラスを安全に無視して、すべての述語に同じ型を使用している限り、 or であると想定できます (これはいつでも実行できます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

a のフィルタリングにQuery[DBUsers]は、 type の述語が必要です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 に答える