fuzzystrmatch
模块提供了几个函数来确定字符串之间的相似度和距离。
目前,soundex
、metaphone
、dmetaphone
和 dmetaphone_alt
函数在处理多字节编码(如 UTF-8)时效果不佳。对于此类数据,请使用 daitch_mokotoff
或 levenshtein
。
此模块被认为是“受信任的”,这意味着非超级用户也可以在其拥有的数据库上安装它,前提是他们具有 CREATE
权限。
Soundex 系统是一种通过将发音相似的名称转换为相同代码来匹配它们的方法。它最初由美国人口普查局在 1880、1900 和 1910 年使用。请注意,Soundex 对于非英语名称不太有用。
fuzzystrmatch
模块提供了两个用于处理 Soundex 编码的函数:
soundex(text) returns text difference(text, text) returns int
soundex
函数将字符串转换为其 Soundex 编码。difference
函数将两个字符串转换为它们的 Soundex 编码,然后报告匹配代码位置的数量。由于 Soundex 编码有四个字符,因此结果的范围是从零到四,其中零表示不匹配,四表示完全匹配。(因此,该函数名称不恰当 — similarity
会是更好的名称。)
以下是一些使用示例:
SELECT soundex('hello world!'); SELECT soundex('Anne'), soundex('Ann'), difference('Anne', 'Ann'); SELECT soundex('Anne'), soundex('Andrew'), difference('Anne', 'Andrew'); SELECT soundex('Anne'), soundex('Margaret'), difference('Anne', 'Margaret'); CREATE TABLE s (nm text); INSERT INTO s VALUES ('john'); INSERT INTO s VALUES ('joan'); INSERT INTO s VALUES ('wobbly'); INSERT INTO s VALUES ('jack'); SELECT * FROM s WHERE soundex(nm) = soundex('john'); SELECT * FROM s WHERE difference(s.nm, 'john') > 2;
与原始 Soundex 系统类似,Daitch-Mokotoff Soundex 通过将发音相似的名称转换为相同代码来匹配它们。然而,Daitch-Mokotoff Soundex 对于非英语名称比原始系统更有用。相比原始系统,主要改进包括:
代码基于前六个有意义的字母,而不是四个。
一个字母或字母组合映射到十种可能的代码,而不是七种。
当两个连续的字母具有单一发音时,它们被编码为单个数字。
当一个字母或字母组合可能具有不同的发音时,会发出多个代码以覆盖所有可能性。
此函数为输入生成 Daitch-Mokotoff soundex 代码。
daitch_mokotoff(source
text) returns text[]
结果可能包含一个或多个代码,具体取决于有多少种可能的发音,因此它被表示为一个数组。
由于 Daitch-Mokotoff soundex 代码仅包含 6 位数字,因此 source
最好是单个单词或名称。
以下是一些示例:
SELECT daitch_mokotoff('George'); daitch_mokotoff ----------------- {595000} SELECT daitch_mokotoff('John'); daitch_mokotoff ----------------- {160000,460000} SELECT daitch_mokotoff('Bierschbach'); daitch_mokotoff ----------------------------------------------------------- {794575,794574,794750,794740,745750,745740,747500,747400} SELECT daitch_mokotoff('Schwartzenegger'); daitch_mokotoff ----------------- {479465}
对于单个名称的匹配,可以使用 &&
运算符直接匹配返回的文本数组:任何重叠都可以视为匹配。可以使用 GIN 索引来提高效率,请参阅 第 65.4 节 和此示例。
CREATE TABLE s (nm text); CREATE INDEX ix_s_dm ON s USING gin (daitch_mokotoff(nm)) WITH (fastupdate = off); INSERT INTO s (nm) VALUES ('Schwartzenegger'), ('John'), ('James'), ('Steinman'), ('Steinmetz'); SELECT * FROM s WHERE daitch_mokotoff(nm) && daitch_mokotoff('Swartzenegger'); SELECT * FROM s WHERE daitch_mokotoff(nm) && daitch_mokotoff('Jane'); SELECT * FROM s WHERE daitch_mokotoff(nm) && daitch_mokotoff('Jens');
对于任何数量名称的任意顺序的索引和匹配,可以使用全文搜索功能。请参阅 第 12 章 和此示例。
CREATE FUNCTION soundex_tsvector(v_name text) RETURNS tsvector BEGIN ATOMIC SELECT to_tsvector('simple', string_agg(array_to_string(daitch_mokotoff(n), ' '), ' ')) FROM regexp_split_to_table(v_name, '\s+') AS n; END; CREATE FUNCTION soundex_tsquery(v_name text) RETURNS tsquery BEGIN ATOMIC SELECT string_agg('(' || array_to_string(daitch_mokotoff(n), '|') || ')', '&')::tsquery FROM regexp_split_to_table(v_name, '\s+') AS n; END; CREATE TABLE s (nm text); CREATE INDEX ix_s_txt ON s USING gin (soundex_tsvector(nm)) WITH (fastupdate = off); INSERT INTO s (nm) VALUES ('John Doe'), ('Jane Roe'), ('Public John Q.'), ('George Best'), ('John Yamson'); SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('john'); SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('jane doe'); SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('john public'); SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('besst, giorgio'); SELECT * FROM s WHERE soundex_tsvector(nm) @@ soundex_tsquery('Jameson John');
如果希望避免在索引重新检查期间重新计算 soundex 代码,可以使用单独列上的索引代替表达式上的索引。可以使用存储的生成列来实现此目的;请参阅 第 5.4 节。
此函数计算两个字符串之间的 Levenshtein 距离。
levenshtein(source text, target text, ins_cost int, del_cost int, sub_cost int) returns int levenshtein(source text, target text) returns int levenshtein_less_equal(source text, target text, ins_cost int, del_cost int, sub_cost int, max_d int) returns int levenshtein_less_equal(source text, target text, max_d int) returns int
source
和 target
都可以是非空字符串,最大长度为 255 个字符。成本参数指定字符插入、删除或替换的费用。您可以省略成本参数,就像函数第二个版本那样;在这种情况下,所有参数都默认为 1。
levenshtein_less_equal
是 Levenshtein 函数的一个加速版本,用于只关心小距离的情况。如果实际距离小于或等于 max_d
,则 levenshtein_less_equal
返回正确距离;否则,它将返回一个大于 max_d
的值。如果 max_d
为负数,则行为与 levenshtein
相同。
示例
test=# SELECT levenshtein('GUMBO', 'GAMBOL'); levenshtein ------------- 2 (1 row) test=# SELECT levenshtein('GUMBO', 'GAMBOL', 2, 1, 1); levenshtein ------------- 3 (1 row) test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 2); levenshtein_less_equal ------------------------ 3 (1 row) test=# SELECT levenshtein_less_equal('extensive', 'exhaustive', 4); levenshtein_less_equal ------------------------ 4 (1 row)
Metaphone 与 Soundex 一样,基于为输入字符串构造代表性代码的思想。然后,如果两个字符串具有相同的代码,则认为它们相似。
此函数计算输入字符串的 metaphone 代码。
metaphone(source text, max_output_length int) returns text
source
必须是非空字符串,最大长度为 255 个字符。max_output_length
设置输出 metaphone 代码的最大长度;如果超过此长度,输出将被截断为该长度。
示例:
test=# SELECT metaphone('GUMBO', 4); metaphone ----------- KM (1 row)
Double Metaphone 系统为给定的输入字符串计算两个“听起来像”的字符串——一个“主要”和一个“备选”。在大多数情况下它们是相同的,但对于非英语名称尤其可能略有不同,具体取决于发音。这些函数计算主要和备选代码。
dmetaphone(source text) returns text dmetaphone_alt(source text) returns text
输入字符串没有长度限制。
示例:
test=# SELECT dmetaphone('gumbo'); dmetaphone ------------ KMP (1 row)
如果您在文档中发现任何不正确、与您在使用特定功能时的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。