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

TypeORM中to_tsquery注入防护与部分全文搜索兼容方案咨询

解决TypeORM中PostgreSQL全文搜索的语法安全与前缀/邻近查询兼容问题

核心思路是通过自定义PostgreSQL函数结合plainto_tsquery和to_tsquery的优势,既处理用户输入的语法安全,又支持前缀匹配(:*)和邻近查询(<->)。

步骤1:创建自定义PostgreSQL函数

在你的PostgreSQL数据库中执行以下SQL,创建兼顾安全与功能的处理函数:

CREATE OR REPLACE FUNCTION safe_prefix_tsquery(query text, config regconfig = 'english')
RETURNS tsquery AS $$
BEGIN
  -- 处理空输入,返回空tsquery避免报错
  IF query IS NULL OR trim(query) = '' THEN
    RETURN ''::tsquery;
  END IF;

  -- 先用plainto_tsquery处理输入,自动转义特殊字符并转换为&连接的tsquery
  -- 再转换为文本,替换&为<->实现邻近匹配,给每个词添加:*实现前缀匹配
  RETURN to_tsquery(
    config,
    replace(
      plainto_tsquery(config, query)::text,
      '&',
      '<->'
    ) || ':*'
  );
EXCEPTION
  -- 极端情况下仍出现语法错误,返回空tsquery
  WHEN OTHERS THEN
    RETURN ''::tsquery;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

这个函数的核心逻辑:

  • 依赖plainto_tsquery自动转义用户输入的特殊字符(如括号、引号),并将空格转换为逻辑与(&)
  • 将转换后的tsquery转为文本,把&替换为<->实现邻近查询
  • 在末尾追加:*实现前缀匹配
  • 异常兜底确保不会因输入问题导致查询报错

步骤2:在TypeORM中使用该函数

通过QueryBuilder构建查询,合并需要搜索的两列,调用自定义函数生成安全的tsquery进行匹配:

import { getConnection } from 'typeorm';

async function searchTargetEntities(query: string) {
  const result = await getConnection()
    .createQueryBuilder()
    .select('entity')
    .from(YourTargetEntity, 'entity')
    // 合并两列生成tsvector,与自定义函数生成的tsquery匹配
    .where(`to_tsvector('english', entity.column1 || ' ' || entity.column2) @@ safe_prefix_tsquery(:query)`)
    .setParameter('query', query)
    .getMany();

  return result;
}

如果需要适配其他语言的文本搜索(比如中文),只需将代码中的'english'替换为对应的PostgreSQL文本搜索配置(如'chinese')。

关键优势

  • 语法安全:彻底避免直接使用to_tsquery时的输入语法报错问题
  • 前缀查询支持:通过追加:*实现关键词的部分匹配
  • 邻近查询支持:将plainto_tsquery生成的逻辑与替换为邻近运算符<->,满足词序邻近的搜索需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:32:21