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

knex.js执行LIKE模式匹配仅返回精确匹配结果如何解决?

问题根因

你的代码没有给LIKE匹配规则添加SQL通配符,最终生成的执行语句等价于:

SELECT * FROM recipes WHERE LOWER(title) LIKE 'test'

SQL语法中,当LIKE后面的匹配串不带%(匹配任意长度任意字符)、_(匹配单个任意字符)这类通配符时,匹配效果和等值判断=完全一致,因此只会返回title完全等于传入值的记录,无法实现模糊匹配。

修复方法

方法1:修正Raw语句的参数,拼接通配符

把通配符和传入的参数值拼接后再做绑定,不要把通配符直接写在Raw SQL字符串里,避免SQL注入风险:

async function getByTitle(title) {
  const result = await db('recipes')
    .select('*')
    // 两边加%代表匹配title中任意位置包含传入值的记录
    .whereRaw('LOWER(title) LIKE ?', [`%${title}%`]);
  return result;
}

如果业务需要匹配「以传入标题开头」的记录,就把参数改成${title}%;如果需要匹配「以传入标题结尾」,就改成%${title}。你当前场景要返回test、test1、test2、test3四条记录,用两边加%的写法即可。

方法2:使用Knex内置查询方法(更推荐)

不需要手写Raw语句,Knex本身对模糊查询有封装,写法更简洁也不容易出语法错误:

// PostgreSQL等支持ilike(大小写不敏感匹配)的数据库可用
async function getByTitle(title) {
  const result = await db('recipes')
    .select('*')
    .where('title', 'ilike', `%${title}%`);
  return result;
}

如果是MySQL、SQLite这类不原生支持ilike的数据库,可以用内置方法统一转义大小写:

// MySQL/SQLite适配写法
async function getByTitle(title) {
  const result = await db('recipes')
    .select('*')
    .whereRaw('LOWER(title) LIKE LOWER(?)', [`%${title}%`]);
  return result;
}
排查步骤

如果修改后仍不符合预期,按以下顺序定位问题:

  • 在查询链末尾调用.toSQL()方法打印Knex实际生成的SQL语句和绑定参数,确认LIKE对应的绑定参数确实携带了%通配符
  • 检查入参处理逻辑,确认传入的title参数没有经过特殊字符过滤,导致拼接的%被提前转义或删除
  • 检查数据库字段的排序规则,确认不存在大小写、字符集相关的匹配异常

内容的提问来源于stack exchange,提问作者David Em-Yinn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:01:25