Prisma调用findMany()执行全文检索报tsquery语法错误
问题根因
该报错是PostgreSQL全文检索执行阶段的语法错误,和数据库连接状态、Prisma Client安装情况无关:
- 错误码
SqlState(E42601)属于SQL语法类错误,报错栈指向PostgreSQL内核tsquery.c文件的makepol方法,触发场景是构造全文检索表达式tsquery时不符合语法规则 - PostgreSQL原生tsquery语法要求多关键词必须通过
&(逻辑与)、|(逻辑或)、!(逻辑非)这类合法运算符分隔,直接传入带空格的字符串Luna Rush时,Prisma的fullTextSearch预览特性不会自动做语法合规转换,数据库会将空格位置判定为缺失运算符的非法节点,直接抛出语法错误。
解决方法
根据实际检索需求选择对应方案即可:
方案1:多词逻辑匹配
直接修改search参数传值,用合法运算符分隔关键词:
- 要求结果同时包含所有关键词,用
&拼接:
const result = await prisma.easytokens.findMany({ where: { tokenName: { search: 'Luna & Rush', }, }, })
- 要求结果包含任意一个关键词,用
|拼接:
search: 'Luna | Rush'
如果需要支持前缀模糊匹配,可以在每个关键词后追加:*,例如传值'Luna:* & Rush:*'即可匹配Luna123、Rush456这类带后缀的字段值。
方案2:精确短语匹配
如果需要匹配字段中连续出现的短语Luna Rush(顺序固定、两词相邻),当前Prisma的fullTextSearch预览特性不支持直接传参实现,需要通过原生SQL调用PostgreSQL内置的phraseto_tsquery函数完成:
const result = await prisma.$queryRaw` SELECT * FROM easytokens WHERE to_tsvector('english', "tokenName") @@ phraseto_tsquery('english', 'Luna Rush') `
优化与避坑
- 全文检索必须搭配GIN索引才能保证大数据量下的查询性能,可以在Prisma Schema的
easytokens模型下添加索引配置,修改后执行prisma generate、prisma db push同步到数据库生效:
model easytokens { // 原有字段定义保持不变 @@index([tokenName], type: Gin) }
- 如果检索关键词来自用户输入,必须提前转义tsquery保留特殊字符(包括
&、|、!、:、*、括号、英文引号等),否则会反复触发同类语法错误,还存在检索逻辑注入风险。
内容的提问来源于stack exchange,提问作者Loco2343
相关产品推荐
相关产品推荐

