【问题标题】:combining slick queries into single query将光滑查询组合成单个查询
【发布时间】:2015-12-21 04:08:11
【问题描述】:

使用 Slick 3.1,我如何将多个查询组合成同一个类型的单个查询?这不是联接或联合,而是组合查询“段”以创建单个查询请求。这些“段”可以是任何单独有效的查询。

val query = TableQuery[SomeThingValid]

// build up pieces of the query in various parts of the application logic
val q1 = query.filter(_.value > 10)
val q2 = query.filter(_.value < 40)
val q3 = query.sortBy(_.date.desc)
val q4 = query.take(5)

// how to combine these into a single query ?
val finalQ = ??? q1 q2 q3 q4 ???

// in order to run in a single request
val result = DB.connection.run(finalQ.result)

编辑: 预期的 sql 应该是这样的:

SELECT * FROM "SomeThingValid" WHERE "SomeThingValid"."value" > 10 AND "SomeThingValid"."valid" < 40 ORDER BY "MemberFeedItem"."date" DESC LIMIT 5

【问题讨论】:

  • 我不完全确定您期望的结果。我想我不得不问:你会如何用普通的 SQL 来做呢?
  • @PatrykĆwiek 更新了示例预期的 sql

标签: scala slick-3.0


【解决方案1】:
val q1 = query.filter(_.value > 10)
val q2 = q1.filter(_.value < 40)
val q3 = q2.sortBy(_.date.desc)
val q4 = q3.take(5)

我认为您应该执行上述操作(并传递 Querys),但如果您坚持传递查询“段”,则类似这样的操作可能有效:

type QuerySegment = Query[SomeThingValid, SomeThingValid, Seq] => Query[SomeThingValid, SomeThingValid, Seq]

val q1: QuerySegment = _.filter(_.value > 10)
val q2: QuerySegment = _.filter(_.value < 40)
val q3: QuerySegment = _.sortBy(_.date.desc)
val q4: QuerySegment = _.take(5)

val finalQ = Function.chain(Seq(q1, q2, q3, q4))(query)

【讨论】:

  • 是的,我可以在查询中添加子句,目标是获取已创建的各种查询并将它们组合在一起以生成示例中的 sql。
  • 很好,谢谢 - 这正是我想要的
  • 我无法传递 Query 的原因是因为 QuerySegments 的生成顺序是不确定的,但我为实际执行构建查询的顺序非常重要。使用您上面概述的技术,我可以获取一组生成的段,并在准备好执行时以正确的顺序组装它们。
【解决方案2】:

我在 slick2.0 中使用过这个“模式”

val query = TableQuery[SomeThingValid]

val flag1, flag3 = false
val flag2, flag4 = true

val bottomFilteredQuery = if(flag1) query.filter(_.value > 10) else query
val topFilteredQuery = if(flag2) bottomFilteredQuery.filter(_.value < 40) else bottomFilteredQuery
val sortedQuery = if(flag3) topFilteredQuery.soryBy(_.date.desc) else topFilteredQuery
val finalQ = if(flag4) sortedQuery.take(5) else sortedQuery

【讨论】:

  • 这在我的情况下不起作用,因为传入的查询是一个不确定的任意集合。
【解决方案3】:

值得一提的是这本精巧的基本书籍,您可能需要避免将多个查询组合在一个查询中。

将动作组合到顺序查询是 Slick 的一项强大功能。 但是,您可以将多个查询减少到一个 数据库查询。如果你能做到这一点,你可能会更好 它。

【讨论】:

    【解决方案4】:

    我认为,它应该工作。但我还没有测试。

    val users = TableQuery[Users]
    val filter1: Query[Users, User, Seq] = users.filter(condition1)
    val filter2: Query[Users, User, Seq] = users.filter(condition2)
    (filter1 ++ filter2).result.headOption
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-07
      • 1970-01-01
      • 1970-01-01
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多