1

ユーザーが部分的なテキストを入力できるようにするオートコンプリートを実装しています。これにより、テーブル内の 4 つの異なる列と照合されます。以下に基本的な例を示します。

+------------+-----------+--------+-----------------+
| first_name | last_name | login  | email           |
+------------+-----------+--------+-----------------+
| John       | Smith     | jsmith | jsmith@foo.bar  |
| Johnny     | Ringo     | ringo  | ringer@hmm.okay |
| Bob        | Jones     | bjones | j1234@xyz.abc   |
| Jane       | Doe       | doej   | doedoe@blah.umm |
+------------+-----------+--------+-----------------+

ユーザーが「jo」と入力すると、4 つの列の少なくとも 1 つがパターン「jo%」と一致するこのテーブルのレコードと一致します。この例では、最初の 2 つだけがfirst_name列の値により一致します。login検索が「js」の場合、そのおよびemail列の値により、最初のレコードのみが一致します。等々。また、最初の結果が「最も近い一致」であるというように、類似性によって並べ替えられた結果を返したいと思います (標準のオートコンプリート動作)。

私は現在UTL_MATCH、次のクエリを生成するコードとを使用してこの問題を解決しようとしています:

SELECT first_name,
  last_name,
  login,
  email,
      (  utl_match.jaro_winkler_similarity(first_name, 'js')
       + utl_match.jaro_winkler_similarity(last_name, 'js')
       + utl_match.jaro_winkler_similarity(login, 'js')
       + utl_match.jaro_winkler_similarity(email, 'js')) similarity
FROM users
WHERE LOWER(first_name) LIKE LOWER('js%')
OR LOWER(last_name) LIKE LOWER('js%')
OR LOWER(login) LIKE LOWER('js%')
OR LOWER(email) LIKE LOWER('js%')
ORDER BY similarity DESC

結果は私が望んでいたほど正確ではありません。私が望むように機能するオートコンプリートを野生で見てきましたが、それらが背面にどのように実装されているかわかりません-終わり。

誰かが私を正しい方向に向けることができますか?

4

1 に答える 1

0

検索はいつも楽しいです。あなたは非常に優れた基本的なアプローチを開始しました。私が通常行うことは、トリガーを介してロードされるセカンダリ テーブルを作成することです。トリガーは users テーブルから主キーをロードし、2 番目の列は「検索」列です。あなたの例では、すべての行で 4 行が生成されます。結果を大文字で保存するようにしてください。これにより、列にインデックスを付けることができ、Oracle は like 構文に固執しているため、インデックスを使用します。追加のテーブルが必要ですが、テーブルはトリガーを介して維持できます。

    create table searcher
    (
    user_id  number, --FK back to users
    search_column  varchar2(50) -- or whatever size column is appropriate
    );

    select u.first_name, u.last_name, u.login. u.email,
utl_match.jaro_winkler_similarity(search_column, 'js')
    from users u
    join
    searcher s
    on (u.user_id = s.user_id)
    where s.search_column like upper('js%')
    order by 5;
于 2012-05-18T02:03:45.370 に答える