【问题标题】:How do I filter an array against a list of strings in Slick如何根据 Slick 中的字符串列表过滤数组
【发布时间】:2019-08-02 01:05:11
【问题描述】:

我有一列包含一个 varchar 数组,以及一个我想与该列匹配的搜索字符串列表。如果任何搜索字符串与列字符串中的任何子字符串匹配,我想返回该行。

例如,如果列包含:

row 1: ['butter', 'water', 'eggs']
row 2: ['apples', 'oranges']
row 3: ['chubby', 'skinny']

我的搜索字符串是:

Set("ter", "hub")

我希望我的过滤结果包含第 1 行和第 3 行,但不包含第 2 行。

如果我用普通的 Scala 写这个,我会这样做:

val rows = [the rows containing my column]
val search = Set("ter", "hub")
rows.filter(r => search.exists(se => r.myColumn.exists(s => s.contains(se))))

在 Slick 中是否有某种方法可以在返回结果之前在 DB 端完成过滤? LIKEANY 的某种组合,也许吧?首先,我对在 SQL 中针对另一个数组过滤数组的机制有点模糊。

【问题讨论】:

    标签: slick


    【解决方案1】:

    虽然我不相信这是最好的方法,但我已经组合了一个使用正则表达式的解决方案。首先,我将搜索词连接成一个简单的正则表达式:

    val matcher = search.mkString(".*(","|",").*") // i.e. '.*(ter|hub).*'
    

    然后我使用隐式 SimpleExpression 连接表列中的数组:

    implicit class StringConcat(s: Rep[List[String]]){
        def stringConcat: Rep[String] = {
          val expr = SimpleExpression.unary[List[String], String] { (s, qb) =>
            qb.sqlBuilder += "array_to_string("
            qb.expr(s)
            qb.sqlBuilder += ", ',')"
          }
          expr.apply(s)
        }
      }
    

    最后,我使用另一个隐式 SimpleExpression 构建了一个正则表达式查询:

    implicit class RegexQuery(s: Rep[String]) {
        def regexQ(p: Rep[String]): Rep[Boolean] = {
          val expr = SimpleExpression.binary[String,String,Boolean] { (s, p, qb) =>
            qb.expr(s)
            qb.sqlBuilder += " ~* "
            qb.expr(p)
          }
          expr.apply(s,p)
        }
      }
    

    然后我可以像这样进行比赛:

    myTable.filter(row => row.myColumn.stringConcat.regexQ(matcher))
    

    希望对某人有所帮助,如果您有更好的方法,请告诉我。

    编辑添加:

    如果您正在寻找完全匹配,而不是部分匹配,您可以使用数组重叠运算符,例如:

    myColumn && '{"water","oranges"}'
    

    在 Slick 中,这是 @& 运算符,就像

    .filter(table => table.myColumn @& myMatchList)
    

    【讨论】:

      猜你喜欢
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-15
      • 2019-03-04
      • 2015-05-08
      • 2011-01-10
      相关资源
      最近更新 更多