gpt4 book ai didi

mysql - 为什么这个 MySQL 双变音位功能不能正常工作?

转载 作者:可可西里 更新时间:2023-11-01 07:53:53 25 4
gpt4 key购买 nike

我刚刚学习 Metaphone 和 Double Metaphone 搜索算法,我有几个问题。根据 Metaphone Wiki 页面,我找到了几个带有实现的来源,特别是 MySQL 实现。我想用我的测试数据库对其进行测试,所以我首先导入了找到的 metaphone.sql 文件(包含双变音位功能)here

现在,我有一张表,国家,在“名称”列中列出了所有国家,例如“阿富汗”、“阿尔巴尼亚”、“ Algolia ”等。因此,首先,我实际上想在表中创建一个新列来存储每个国家/地区的双音位字符串。我运行了以下代码:

UPDATE country SET NameDM = dm(name)

一切正常。阿富汗的变音位字符串是“AFKNSTN”,阿尔巴尼亚的是“ALPN”, Algolia 的是“ALKR;ALJR”等等。“太棒了,”我想。

但是,当我尝试查询该表时,我没有得到任何结果。根据 metaphone.sql 的作者,我遵循以下 SQL 语句的语法:

SELECT Name FROM tblPeople WHERE dm(Name) = dm(@search)

因此,我将此代码更改为以下内容:

SELECT * FROM country WHERE dm(name) = dm(@search)

当然,我将“@search”更改为我要查找的任何搜索词,但每次 SQL 查询后我都得到 0 个结果。

谁能解释一下这个问题?我是不是遗漏了什么重要的东西,或者我只是误解了 Metaphone 算法?

谢谢!

最佳答案

当比较 dm() 输出时,我使用以下函数来允许更高级别的模糊性。直接检查 dm('smith') != dm('schmitt') 对大量名称失败,包括我自己的常见拼写错误。

该函数创建了一个介于 0.0 和 1.0 之间的匹配权重(我希望如此),它允许我对每个返回的行进行排名,并选择那些有益的,0.3 是捕获奇怪发音的一个很好的值,0.5 更常见。

dmcompare(dm("boothroyd"), dm("boofreed")) = 0.3
dmcompare(dm("smith"), dm("scmitt")) = 0.5

注意这是双元音字符串和不是原始字符串的比较,这是为了性能问题,我的数据库包含变音位列以及原始字符串。

    CREATE FUNCTION `dmcompare`(leftValue VARCHAR(55), rightValue VARCHAR(55))         RETURNS DECIMAL(2,1)     NO SQL    BEGIN    ---------------------------------------------------------------------------------------    -- Compare two (double) metaphone strings for potential similarlity, i.e.    --    dm("smith") != dm("schmitt")  :: "SM0;XMT" != "XMT;SMT"     --  dmcompare( dm('smith'), dm('schmitt' ) returns 0,5    -- @author: P.Boothroyd    -- @version: 0.9, 08/01/2013    -- The values here can still be played with    -- (c) GNU P L - feel free to share and adapt, but please acknowledge the original code    ---------------------------------------------------------------------------------------        DECLARE leftPri, leftSec, rightPri, rightSec VARCHAR(55) DEFAULT '';        DECLARE sepPos INT;        DECLARE retValue DECIMAL(2,1);        DECLARE partMatch BOOLEAN;        -- Extract the metaphone tags        SET sepPos = LOCATE(";", leftValue);        IF sepPos = 0 THEN            SET sepPos = LENGTH(leftValue) + 1;        END IF;        SET leftPri = LEFT(leftValue, sepPos - 1);        SET leftSec = MID(leftValue, sepPos + 1, LENGTH( leftValue ) - sepPos);        SET sepPos = LOCATE(";", rightValue);        IF sepPos = 0 THEN            SET sepPos = LENGTH(rightValue) + 1;        END IF;        SET rightPri = LEFT(rightValue, sepPos - 1);        SET rightSec = MID(rightValue, sepPos + 1, LENGTH( rightValue ) - sepPos);        -- Calculate likeness factor        SET retValue = 0;        SET partMatch = FALSE;        -- Primaries equal 50% match        IF leftPri = rightPri THEN            SET retValue = retValue + 0.5;            SET partMatch = TRUE;        ELSE            IF SOUNDEX(leftPri) = SOUNDEX(rightPri) THEN                SET retValue = retValue + 0.3;                SET partMatch = TRUE;            END IF;        END IF;        -- Test alternate primary and secondaries, worth 30% match        IF leftSec = rightPri THEN            SET retValue = retValue + 0.3;            SET partMatch = TRUE;            IF SOUNDEX(leftSec) = SOUNDEX(rightPri) THEN                SET retValue = retValue + 0.2;                SET partMatch = TRUE;            END IF;        END IF;        -- Test alternate primary and secondaries, worth 30% match        IF leftPri = rightSec THEN            SET retValue = retValue + 0.3;            SET partMatch = TRUE;            IF SOUNDEX(leftPri) = SOUNDEX(rightSec) THEN                SET retValue = retValue + 0.2;                SET partMatch = TRUE;            END IF;        END IF;        -- Are secondary values the same or both NULL        IF leftSec = rightSec THEN            -- No secondaries ...            IF leftSec = '' THEN                -- If there is prior matching then no secondaries is 40%                IF partMatch = TRUE THEN                    SET retValue = retValue + 0.4;                END IF;            ELSE                -- If the secondaries match then 50% match                SET retValue = retValue + 0.5;            END IF;        ELSE            IF SOUNDEX(leftSec) = SOUNDEX(rightSec) THEN                IF leftSec = '' THEN                    IF partMatch = TRUE THEN                        SET retValue = retValue + 0.3;                    END IF;                END IF;            END IF;         END IF;        RETURN (retValue);    END

请随意使用代码,但也请提及此代码的来源 P.Boothroyd 任何用法 - 即更改值等。

干杯,保罗

关于mysql - 为什么这个 MySQL 双变音位功能不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10359637/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com