web-dev-qa-db-ja.com

Oracleでのファジーテキスト検索

600000以上の行がある国全体のストリート名を含む大きなOracleDBテーブルがあります。私のアプリケーションでは、住所文字列を入力として受け取り、この住所文字列の特定の部分文字列がテーブル内の1つまたは複数の通りの名前と一致するかどうかを確認して、その住所の部分文字列を通りの名前としてラベル付けできるようにします。

明らかに、これはあいまいなテキスト一致の問題であるはずです。クエリした部分文字列がDBテーブルのストリート名と完全に一致する可能性はごくわずかです。したがって、ある種のあいまいテキストマッチングアプローチが必要です。 CONTAINSおよびCATSEARCH検索演算子が説明されている http://docs.Oracle.com/cd/B28359_01/text.111/b28303/query.htm でOracleのドキュメントを読み込もうとしています。しかし、これらは、ドキュメント内の特定の文字列に一致するものを検索するなど、より複雑なタスクに使用されているようです。テーブルの列に対してそれを実行したいだけです。

この場合、オラクルはそのような種類のあいまいテキストマッチングクエリをサポートしていますか?

11
Ufuk Can Bicici

TL_MATCH 文字列を照合し、それらの類似性を比較するためのメソッドが含まれています。レーベンシュタイン距離とも呼ばれる編集距離は、開始するのに適した場所である可能性があります。 1つの文字列は部分文字列であるため、文字列のサイズに対する編集距離を比較すると役立つ場合があります。

--Addresses that are most similar to each substring.
select substring, address, edit_ratio
from
(
    --Rank edit ratios.
    select substring, address, edit_ratio
        ,dense_rank() over (partition by substring order by edit_ratio desc) edit_ratio_rank
    from
    (
        --Calculate edit ratio - edit distance relative to string sizes.
        select
            substring,
            address,
            (length(address) - UTL_MATCH.EDIT_DISTANCE(substring, address))/length(substring) edit_ratio
        from
        (
            --Fake addreses (from http://names.igopaygo.com/street/north_american_address)
            select '526 Burning Hill Big Beaver District of Columbia 20041'   address from dual union all
            select '5206 Hidden Rise Whitebead Michigan 48426'                address from dual union all
            select '2714 Noble Drive Milk River Michigan 48770'               address from dual union all
            select '8325 Grand Wagon Private Sleeping Buffalo Arkansas 72265' address from dual union all
            select '968 Iron Corner Wacker Arkansas 72793'                    address from dual
        ) addresses
        cross join
        (
            --Address substrings.
            select 'Michigan'           substring from dual union all
            select 'Not-So-Hidden Rise' substring from dual union all
            select '123 Fake Street'    substring from dual
        )
        order by substring, edit_ratio desc
    )
)
where edit_ratio_rank = 1
order by substring, address;

これらの結果は素晴らしいものではありませんが、うまくいけば、これは少なくとも良い出発点です。どの言語でも機能するはずです。ただし、これを言語またはロケール固有の比較ルールと組み合わせることもできます。

SUBSTRING          ADDRESS                                                  EDIT_RATIO
---------          -------                                                  ----------
123 Fake Street    526 Burning Hill Big Beaver District of Columbia 20041   0.5333
Michigan           2714 Noble Drive Milk River Michigan 48770               1
Michigan           5206 Hidden Rise Whitebead Michigan 48426                1
Not-So-Hidden Rise 5206 Hidden Rise Whitebead Michigan 48426                0.5
8
Jon Heller

Oracleデータベースで使用可能な [〜#〜] soundex [〜#〜] 関数を利用できます。 SOUNDEXは、テキスト文字列の数値署名を計算します。これを使用して、類似しているように聞こえる文字列を検索し、文字列比較の数を減らすことができます。

編集済み:SOUNDEXが現地の言語に適していない場合は、Googleより優れたパフォーマンスを発揮する音声署名または音声マッチング機能の場合。この関数は、新しいテーブルエントリごとに1回、クエリごとに1回評価する必要があります。したがって、Oracleに常駐する必要はありません。

例:トルコのSOUNDEXが宣伝されています ここ

マッチングの品質を高めるには、最初のステップで通りの名前のスペルを統一する必要があります。これは、一連のルールを適用することで実行できます。

簡略化されたサンプルルール:

  1. すべての文字を小文字に変換します
  2. 「str」を削除します。名前の最後に
  3. 「drv」を削除します。名前の最後に
  4. 名前の末尾の「場所」を削除します
  5. 「ave」を削除します。名前の最後に
  6. 複数の単語を含む名前をアルファベット順に並べ替える
  7. 「of」、「and」、「the」、...などの補助語を削除します。
2
Axel Kemper