NestJS中TypeORM是否支持PostgreSQL的无重音模糊搜索?
问题:TypeORM + PostgreSQL 无法检索带重音字符(如é、ü)
我在NestJS中使用TypeORM搭建了如下搜索函数:
public async getAllRecipesBySearchTerm( searchTerm: string, ): Promise<Recipe[]> { return await this.repository.find({ where: { title: ILike('%' + searchTerm + '%') }, }); }
当前当食谱标题包含é、ü这类带重音的字符时,无法被检索到。我了解PostgreSQL支持这类查询,请问TypeORM是否支持该功能?
解决方案
TypeORM完全支持结合PostgreSQL的非重音查询能力,核心是利用PostgreSQL的unaccent扩展和函数实现忽略重音的匹配。
第一步:启用PostgreSQL的unaccent扩展
先在数据库中执行以下SQL命令:CREATE EXTENSION IF NOT EXISTS unaccent;第二步:修改TypeORM查询逻辑
你可以通过两种方式实现忽略重音的检索:方式一:使用QueryBuilder(推荐,更灵活)
public async getAllRecipesBySearchTerm(searchTerm: string): Promise<Recipe[]> { const unaccentedSearchTerm = `%${searchTerm}%`; return this.repository .createQueryBuilder('recipe') .where('unaccent(recipe.title) ILIKE unaccent(:searchTerm)', { searchTerm: unaccentedSearchTerm }) .getMany(); }方式二:使用Raw函数(适配原有find方法风格)
import { Raw } from 'typeorm'; public async getAllRecipesBySearchTerm(searchTerm: string): Promise<Recipe[]> { return this.repository.find({ where: { title: Raw(alias => `unaccent(${alias}) ILIKE unaccent('%${searchTerm}%')`) } }); }第三步:性能优化(可选)
如果该查询调用频繁,建议给unaccent(title)创建GIN索引,大幅提升检索速度:CREATE INDEX idx_recipe_title_unaccent ON recipe USING gin (unaccent(title) gin_trgm_ops);
以上方案本质是借助PostgreSQL的unaccent函数去除字符重音后再做模糊匹配,TypeORM只是提供了调用数据库原生函数的能力,完美解决带重音字符的检索问题。
内容的提问来源于stack exchange,提问作者Bowis
相关产品推荐
相关产品推荐

