如何在Prisma中实现浮点数的模糊搜索?
在Prisma中实现浮点数的模糊/前缀匹配搜索
Prisma本身没有为数值类型提供直接的模糊匹配API,但可以通过将数值转换为字符串后复用字符串搜索逻辑来实现需求,以下是几种可行方案:
1. 使用数据库原生函数的Raw查询
直接借助数据库的类型转换函数,把浮点数转为字符串后执行LIKE匹配,这是最直接的实现方式。
示例(PostgreSQL)
如果你的数据库是PostgreSQL,推荐用TO_CHAR函数格式化浮点数(避免科学计数法问题),再实现包含或前缀匹配:
const searchTerm = '36'; const results = await prisma.yourModel.findMany({ where: { OR: [ // 匹配任意位置包含36的数值(如23.36、360) prisma.raw(`TO_CHAR(yourFloatColumn, 'FM9999999999999999.999999') LIKE '%' || $1 || '%'`, [searchTerm]), // 仅匹配以36开头的数值(如36、362) prisma.raw(`TO_CHAR(yourFloatColumn, 'FM9999999999999999.999999') LIKE $1 || '%'`, [searchTerm]), ], }, });
注:FM修饰符用于去掉数值前后的空格,格式字符串可根据你的数值范围调整长度。
示例(MySQL)
MySQL可以用CONVERT函数将浮点数转为字符串:
const searchTerm = '36'; const results = await prisma.yourModel.findMany({ where: { OR: [ // 包含匹配 prisma.raw(`CONVERT(yourFloatColumn, CHAR) LIKE CONCAT('%', ?, '%')`, [searchTerm]), // 前缀匹配 prisma.raw(`CONVERT(yourFloatColumn, CHAR) LIKE CONCAT(?, '%')`, [searchTerm]), ], }, });
2. 优化方案:同步存储字符串版本的数值
如果数据量较大,数值转字符串的搜索无法利用数值索引,会影响性能。可以在数据表中新增一个字符串类型的字段(比如floatAsString),在创建或更新数据时同步将浮点数转为格式化后的字符串存储,之后直接用Prisma的字符串搜索API:
// 创建数据时同步生成字符串版本 await prisma.yourModel.create({ data: { yourFloatColumn: 360, floatAsString: '360' // 或用数据库函数自动生成 } }); // 搜索时直接用字符串模糊匹配 const results = await prisma.yourModel.findMany({ where: { OR: [ { floatAsString: { contains: '36' } }, { floatAsString: { startsWith: '36' } } ] } });
关键注意事项
- 防SQL注入:所有用户输入的搜索词必须用参数化查询(如上述示例中的
$1或?占位符),禁止直接拼接字符串。 - 科学计数法处理:如果浮点数可能出现
1e+05这类科学计数法格式,需要调整转换函数的参数,确保输出为常规十进制字符串(比如PostgreSQL的TO_CHAR指定足够长的格式)。
内容的提问来源于stack exchange,提问作者Justin Handley
相关产品推荐
相关产品推荐

