繁体   English   中英

在 SQL 中的部分字符串上使用 levenshtein

[英]Using levenshtein on parts of string in SQL

我试图找出一种使用 Levenshtein 方法将一些模糊搜索方法用于我们的店面搜索字段的方法,但我遇到了如何仅搜索部分产品名称的问题。

例如,客户搜索scisors ,但我们有一个产品叫electric scissor 使用 Levenshtein 方法levenshtein("scisors","electric scissor")我们将得到 11 的结果,因为电动部分将被计为差异。

我正在寻找的是一种查看产品名称子字符串的方法,因此它会将其与levenshtein("scisors","electric")levenshtein("scisors","scissor")进行比较以查看我们在第二个 substring 中只能得到 2 的结果,因此将该产品显示为搜索结果的一部分。

非工作示例让您了解我所追求的:

SELECT * FROM products p WHERE levenshtein("scisors", p.name) < 5

问题:有没有办法编写处理检查字符串部分的 SQL 语句? 我是否需要在我的数据库中创建更多函数才能处理它,或者修改我现有的 function,如果需要,它会是什么样子?

我目前正在使用 levenshtein 方法的这个实现:

//levenshtein(s1 as VARCHAR(255), s2 as VARCHAR(255))
//returns int


  BEGIN
    DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
    DECLARE s1_char CHAR;
    -- max strlen=255
    DECLARE cv0, cv1 VARBINARY(256);
    SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
    IF s1 = s2 THEN
      RETURN 0;
    ELSEIF s1_len = 0 THEN
      RETURN s2_len;
    ELSEIF s2_len = 0 THEN
      RETURN s1_len;
    ELSE
      WHILE j <= s2_len DO
        SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
      END WHILE;
      WHILE i <= s1_len DO
        SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
        WHILE j <= s2_len DO
          SET c = c + 1;
          IF s1_char = SUBSTRING(s2, j, 1) THEN 
            SET cost = 0; ELSE SET cost = 1;
          END IF;
          SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
          IF c > c_temp THEN SET c = c_temp; END IF;
            SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
            IF c > c_temp THEN 
              SET c = c_temp; 
            END IF;
            SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
        END WHILE;
        SET cv1 = cv0, i = i + 1;
      END WHILE;
    END IF;
    RETURN c;
  END

这是一个有点长的评论。

首先,我建议使用带有同义词列表的全文搜索。 也就是说,您的用户可能拼写能力很差,因此同义词列表可能难以维护。

如果您使用 Levenshtein 距离,那么我建议您按单词进行。 对于用户输入中的每个单词,计算name字段中最接近的单词 然后将它们加在一起以获得最佳匹配。

在您的示例中,您将进行以下比较:

  • levenshtein('剪刀','电动')
  • levenshtein('剪刀', '剪刀')

最小值将是第二个。 如果用户键入多个单词,例如'electrk scisors' ,那么你会做

  • levenshtein('electrk', 'electric') <-- 最小值
  • levenshtein('electrk', '剪刀')
  • levenshtein('剪刀','电动')
  • levenshtein('scisors', 'scissor') <-- 最小值

这可能是一种接近搜索的直观方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM