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 索引可用於提高效率,請參閱 第 64.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)
如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的內容,請使用此表單來報告文件問題。