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

Slick操作PostgreSQL如何对字符串数组使用like运算符实现模糊查询

错误原因

你遇到的报错是因为Slick生成的any("keywords") like '%foo%'不符合PostgreSQL的语法规范,PostgreSQL不支持直接对ANY()返回的数组元素序列做LIKE匹配。


解决方案

方案1:使用unnest拆解数组匹配(最稳妥,无副作用)

PostgreSQL中要对数组的每个元素做模糊匹配,正确的写法是通过unnest把数组转为行,再用EXISTS判断是否有满足匹配的元素:

SELECT * FROM foos 
WHERE EXISTS (
  SELECT 1 FROM unnest(keywords) AS keyword 
  WHERE keyword LIKE '%搜索词%'
);

推荐直接用Slick Plain SQL写查询,逻辑更清晰,避免API映射错误:

import slick.jdbc.PostgresProfile.api._
import java.util.UUID

// 假设你的表映射定义如下
case class Foo(id: Option[UUID], keywords: Seq[String])
class FooTable(tag: Tag) extends Table[Foo](tag, "foos") {
  def id = column[UUID]("id", O.PrimaryKey)
  def keywords = column[Seq[String]]("keywords")
  override def * = (id.?, keywords) <> (Foo.tupled, Foo.unapply)
}
val Foos = TableQuery[FooTable]

def searchKeywords(txt: String): Future[Seq[Foo]] = {
  val searchPattern = s"%$txt%"
  val query = sql"""
    SELECT id, keywords FROM foos
    WHERE EXISTS (
      SELECT 1 FROM unnest(keywords) AS k
      WHERE k LIKE $searchPattern
    )
  """.as[Foo]
  db.run(query)
}

方案2:数组转字符串后匹配(更简洁,有前提限制)

如果你的关键词内容不会包含固定分隔符(比如逗号、特殊符号),可以直接把整个数组拼接成字符串后做LIKE匹配,代码更简洁:

SELECT * FROM foos WHERE array_to_string(keywords, ',') LIKE '%搜索词%'

可以自定义Slick函数映射来兼容Query API的写法:

import slick.jdbc.PostgresProfile.api._

// 自定义array_to_string函数映射
def arrayToString[T](arr: Rep[Seq[T]], sep: Rep[String]): Rep[String] = 
  SimpleFunction.binary[Seq[T], String, String]("array_to_string").apply(arr, sep)

def searchKeywords(txt: String): Future[Seq[Foo]] = {
  val searchPattern = s"%$txt%"
  val action = Foos.filter(f => arrayToString(f.keywords, ",").like(searchPattern)).result
  db.run(action)
}

性能优化建议

如果数据量较大,LIKE模糊搜索的性能会比较差,推荐:

  • 给字段创建GIN索引,改用PostgreSQL全文搜索功能实现匹配
  • 对关键词数组做预处理,提前生成tsvector向量存储,匹配时用@@全文匹配运算符,性能提升非常明显

内容的提问来源于stack exchange,提问作者schub

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 18:09:02