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

如何在基于MySQL的Strapi CMS中实现模糊搜索?

在MySQL版Strapi中实现近似模糊搜索的方案

我来分享几个在MySQL版Strapi中实现这种近似模糊搜索的可行方案,刚好能满足你提到的'tvs ad'匹配'tv syd'这类发音/拼写近似的需求:

方案一:利用MySQL的SOUNDEX/SOUNDS LIKE(发音相似匹配)

这是最贴合你示例场景的方案,因为SOUNDS LIKE是基于发音规则的匹配,能识别发音相近的单词组合。

实现步骤:

  1. 创建自定义控制器:在你的目标内容类型控制器中添加搜索方法,比如api/your-content-type/controllers/your-content-type.js:
module.exports = {
  async phoneticSearch(ctx) {
    const { keyword } = ctx.query;
    if (!keyword) {
      return ctx.badRequest('搜索关键词不能为空');
    }

    // 将关键词拆分为独立词汇,分别匹配发音
    const searchTerms = keyword.split(' ').filter(term => term.trim().length > 0);
    
    // 构建SQL查询,每个词汇用SOUNDS LIKE匹配目标字段(这里假设字段名为name)
    let sqlQuery = 'SELECT * FROM your_content_type_table WHERE 1=1';
    const queryParams = [];

    searchTerms.forEach((term) => {
      sqlQuery += ' AND SOUNDEX(name) SOUNDS LIKE SOUNDEX(?)';
      queryParams.push(term);
    });

    // 执行原生SQL查询
    const searchResults = await strapi.db.connection.raw(sqlQuery, queryParams);
    return ctx.send(searchResults[0]);
  }
};

注意:把your_content_type_table替换成你实际的数据库表名(Strapi表名一般是内容类型的复数形式,比如items),name替换成你要搜索的字段名。

  1. 测试接口:启动Strapi后,访问http://your-strapi-url/api/your-content-type/phonetic-search?keyword=tvs ad,就能获取发音匹配的结果。

优缺点:

  • ✅ 优点:实现简单,完全基于MySQL原生功能,对英语发音相似的匹配效果好,正好适配你的示例需求。
  • ❌ 缺点:对非英语语言支持较差,发音规则适配有限。

方案二:MySQL全文索引(FULLTEXT)

如果你的数据量较大,需要更高效的模糊搜索,可以用MySQL的全文索引功能,支持关键词的近似匹配和权重排序。

实现步骤:

  1. 创建全文索引:先给目标字段创建全文索引(比如给name字段):
ALTER TABLE your_content_type_table ADD FULLTEXT INDEX idx_fulltext_name (name);

注意:MySQL默认全文索引的最小词长是4,如果你需要搜索短词(比如示例中的tv),需要修改MySQL配置ft_min_word_len=2,然后重建索引。

  1. 编写Strapi搜索控制器:
module.exports = {
  async fulltextSearch(ctx) {
    const { keyword } = ctx.query;
    if (!keyword) {
      return ctx.badRequest('搜索关键词不能为空');
    }

    // 使用BOOLEAN模式,支持通配符和近似匹配
    const searchResults = await strapi.db.connection.raw(
      `SELECT *, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS relevance 
       FROM your_content_type_table 
       WHERE MATCH(name) AGAINST(? IN BOOLEAN MODE)
       ORDER BY relevance DESC`,
      [`*${keyword}*`, `*${keyword}*`]
    );

    return ctx.send(searchResults[0]);
  }
};

*${keyword}*表示匹配包含关键词任意部分的内容,BOOLEAN模式还支持+(必须包含)、-(排除)等语法。

优缺点:

  • ✅ 优点:搜索效率高,适合大数据量,支持复杂的关键词组合匹配。
  • ❌ 缺点:近似匹配的灵活性不如发音匹配或编辑距离,短词需要调整MySQL配置。

方案三:Levenshtein编辑距离(拼写相似匹配)

如果需要基于拼写的相似度(比如允许一定数量的拼写错误),可以用Levenshtein距离计算两个字符串的编辑次数,筛选距离较小的结果。

实现步骤:

  1. 在MySQL中创建Levenshtein函数:先在你的MySQL数据库中执行以下SQL创建自定义函数:
DELIMITER //
CREATE FUNCTION LEVENSHTEIN(s1 VARCHAR(255), s2 VARCHAR(255)) 
RETURNS INT 
DETERMINISTIC 
BEGIN 
    DECLARE s1_len, s2_len, i, j, c, c_temp INT; 
    DECLARE s1_char CHAR; 
    DECLARE cv0, cv1 VARBINARY(256); 
    SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2); 
    IF s1_len = 0 THEN RETURN s2_len; END IF; 
    IF s2_len = 0 THEN RETURN s1_len; END IF; 
    SET cv0 = 0x00; 
    FOR i FROM 1 TO s2_len DO 
        SET cv0 = CONCAT(cv0, UNHEX(HEX(i))); 
    END FOR; 
    FOR i FROM 1 TO s1_len DO 
        SET s1_char = SUBSTRING(s1, i, 1), cv1 = UNHEX(HEX(i)), j = 1; 
        FOR j FROM 1 TO s2_len DO 
            SET c = IF(s1_char = SUBSTRING(s2, j, 1), 0, 1); 
            SET c_temp = CONV(HEX(SUBSTRING(cv0, j, 1)), 16, 10) + c; 
            SET cv1 = CONCAT(cv1, UNHEX(HEX(IF(CONV(HEX(SUBSTRING(cv0, j+1, 1)), 16, 10) + 1 > c_temp, c_temp, CONV(HEX(SUBSTRING(cv0, j+1, 1)), 16, 10) + 1)))); 
        END FOR; 
        SET cv0 = cv1; 
    END FOR; 
    RETURN CONV(HEX(SUBSTRING(cv0, s2_len+1, 1)), 16, 10); 
END//
DELIMITER ;
  1. 编写Strapi搜索控制器:
module.exports = {
  async fuzzySearch(ctx) {
    const { keyword } = ctx.query;
    if (!keyword) {
      return ctx.badRequest('搜索关键词不能为空');
    }

    // 设置最大允许的编辑距离(比如2,表示最多2个字符的差异)
    const maxDistance = 2;
    const searchResults = await strapi.db.connection.raw(
      `SELECT *, LEVENSHTEIN(name, ?) AS distance 
       FROM your_content_type_table 
       WHERE LEVENSHTEIN(name, ?) <= ? 
       ORDER BY distance ASC`,
      [keyword, keyword, maxDistance]
    );

    return ctx.send(searchResults[0]);
  }
};

优缺点:

  • ✅ 优点:精准控制拼写相似度,适合处理拼写错误的搜索请求,支持所有语言。
  • ❌ 缺点:计算量较大,数据量非常大时可能影响性能,需要合理设置最大距离。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 03:02:39