2013-10-18 91 views
0

在PL/SQL中執行詞匹配搜索的最佳方法是什麼?使用PL/SQL搜索詞匹配

E.g.字符串 「CHELTENHAM LIMITED的BROUGHTONS

「BROUGHTONS有限公司」 是一個比賽

「有限的」,是一個比賽

「CHELTENHAM BROUGHTONS」 是比賽

「BROUG」是不匹配

+0

就像在賓利經銷商那樣?小世界;)無論如何,要隱約回答你的問題,你需要標記搜索字符串,然後查詢令牌...... [我爲個人名稱做了類似的事情](http://xoph.co/20111007/building-a-better-search-engine /),你可以相對容易地適應你的需求。如果你想得到更好的建議,那就去嘗試一下吧。 – Xophmeister

回答

4

這是一個相當粗糙的方法,但應該做你所問的。正如Xophmeister指出的那樣,您可能需要對每個字符串進行標記,然後搜索標記(因爲您想按順序進行匹配,做一個簡單的「像%tokenA%tokenB%tokenC%」將不起作用)。

此外,這甚至不涉及語音,soundex等所有問題。但再次,不是你問了什麼。這也不會觸及性能或縮放問題,並且可能僅適用於一小部分數據。

所以,首先我們需要一個分裂的功能:

create or replace 
function fn_split(i_string in varchar2, i_delimiter in varchar2 default ',', b_dedup_tokens in number default 0) 
return sys.dbms_debug_vc2coll 
as 
    l_tab sys.dbms_debug_vc2coll; 
begin 
    select regexp_substr(i_string,'[^' || i_delimiter || ']+', 1, level) 
    bulk collect into l_tab 
    from dual 
    connect by regexp_substr(i_string, '[^' || i_delimiter || ']+', 1, level) is not null 
    order by level; 

    if (b_dedup_tokens > 0) then 
    return l_tab multiset union distinct l_tab; 
    end if; 
    return l_tab; 
end; 

現在,我們可以用它來檢查特定的標記字符串。在這裏我從樣本數據集

的搜索3個令牌(約翰Q公衆)
with test_data as (
    select 1 as id, 'John Q Public' as full_name from dual 
    union 
    select 2 as id, 'John John Smith' as full_name from dual 
    union 
    select 3 as id,'Sally Smith' from dual 
    union 
    select 4 as id, 'Mr John B B Q Public' from dual 
    union 
    select 5 as id, 'A Public John' from dual 
) 
select d.id, d.full_name, count(1) as hits 
from test_data d, table(fn_split(full_name, ' ', 1)) 
-- should have at least 1 of these tokens 
where column_value in ('John', 'Q', 'Public') 
group by d.id, d.full_name 
-- can also restrict results to those with at least x token hits 
having count(1) >= 2 
-- most hits at top of results 
order by count(1) desc, id asc 

輸出:

"ID" "FULL_NAME" "HITS" 
1 "John Q Public" 3 
4 "Mr John B B Q Public" 3 
5 "A Public John" 2 

您還可以添加「上」做出區分大小寫等