0

PL/SQLで単語一致検索を行う最良の方法は何ですか?

たとえば、文字列「BROUGHTONS OF CHELTENHAM LIMITED」の場合

「BROUGHTONS LIMITED」がマッチ

「OF LIMITED」がマッチ

「CHELTENHAM BROUGHTONS」がマッチ

「BROUG」は不一致

4

2 に答える 2

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 つのトークン (John Q Public) を検索しています。

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

「大文字」を追加して、大文字と小文字を区別しないなどにすることもできます。

于 2013-10-18T19:50:07.587 に答える
0

Oracle Text 索引を使用します。これにより、強力な CONTAINS クエリを発行できます。

http://docs.oracle.com/cd/B28359_01/text.111/b28303/quicktour.htm

于 2013-10-21T07:48:40.180 に答える