2015-07-03 54 views
2

我正在開發一個postgreSQL查詢,以便在我正在處理的應用程序中搜索公司名稱時允許使用模糊搜索功能。我發現並一直在使用Postgres的Levenshtein方法(fuzzystrmatch模塊的一部分),並且大部分工作正常。但是,它似乎只工作時,公司的名稱是一個字,例如:PostgreSQL模糊使用Levenshtein搜索多個單詞

與蘋果(它存儲在數據庫中,只是蘋果)我可以運行以下查詢,並使其工作接近完美(它返回0 Levenshtein距離):

SELECT * FROM contents 
    WHERE levenshtein(company_name, 'apple') < 4; 

然而,當我需要與索尼(存儲在數據庫中的索尼電子INC)我無法得到任何有用的結果同樣的方法(進入索尼給出了Levenshtein距離16)。

我試圖打破該公司的名稱分解成單個的單詞和單獨輸入每一個,導致這樣的事情來解決這個問題:

user input => 'sony' 

SELECT * FROM contents 
    WHERE levenshtein('Sony', 'sony') < 4 
    OR levenshtein('Electronics', 'sony') < 4 
    OR levenshtein('INC', 'sony') < 4; 

所以我的問題是這樣的:有一些方式,我可以用現在的一般方法準確地實現多詞模糊搜索,或者我正在尋找完全錯誤的地方?

謝謝!

回答

0

鑑於你的數據和與用於的Levenshtein插入(10000),缺失野生值(100)和替換(1)成本以下查詢:

with sample_data as (select 101 "id", 'Sony Entertainment Inc' as "name" 
         union 
        select 102 "id",'Apple Corp' as "name") 
select sample_data.id,sample_data.name, components.part, 
     levenshtein(components.part,'sony',10000,100,1) ld_sony 
from sample_data 
inner join (select sd.id, 
        lower(unnest(regexp_split_to_array(sd.name,E'\\s+'))) part 
      from sample_data sd) components on components.id = sample_data.id 

的輸出是這樣:

id |   name   |  part  | ld_sony 
-----+------------------------+---------------+--------- 
101 | Sony Entertainment Inc | sony   |  0 
101 | Sony Entertainment Inc | entertainment |  903 
101 | Sony Entertainment Inc | inc   | 10002 
102 | Apple Corp    | apple   |  104 
102 | Apple Corp    | corp   |  3 
(5 rows) 
  • 行1 - 無變化..
  • 行2 - 9個缺失和3改變
  • 行3 - 1 inser重刑和2改變
  • 行4 - 1缺失和4改變
  • 行5 - 3改變

我發現,分裂出來的話引起了很多誤報磨片你給一個門檻。您可以通過Levenshtein距離進行排序,以便將較好的匹配置於靠近頂部的位置。也許調整Levenshtein變量可以幫助你更好地排序。令人遺憾的是,Levenshtein不會比以後的變化加重更早的變化。