5

ほとんどが映画やテレビ番組の名前である約 20 ~ 30k のレコードを検索する必要があるサイトがあります。このサイトでは、memcache を使用して php/mysql を実行しています。

私は現在持っている検索に置き換えようとFULLTEXTsoundex()ていますが、これはうまくいきます...しかし、多くの状況ではあまり良くありません。

実装が簡単で、適切な検索機能 (テーブル内の 3 列) を提供する適切な検索スクリプトはありますか?

4

4 に答える 4

7

ewemli の答えは正しい方向ですが、フルテキストを置き換えるのではなく、FULLTEXT と soundex マッピングを組み合わせる必要があります。そうしないと、LIKE クエリが非常に遅くなる可能性があります。

create table with_soundex (
  id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
  original TEXT,
  soundex TEXT,
  FULLTEXT (soundex)
);

insert into with_soundex (original, soundex) values 

('add some test cases', CONCAT_WS(' ', soundex('add'), soundex('some'), soundex('test'), soundex('cases'))),
('this is some text', CONCAT_WS(' ', soundex('this'), soundex('is'), soundex('some'), soundex('text'))),
('one more test case', CONCAT_WS(' ', soundex('one'), soundex('more'), soundex('test'), soundex('case'))),
('just filling the index', CONCAT_WS(' ', soundex('just'), soundex('filling'), soundex('the'), soundex('index'))),
('need one more example', CONCAT_WS(' ', soundex('need'), soundex('one'), soundex('more'), soundex('example'))),
('seems to need more', CONCAT_WS(' ', soundex('seems'), soundex('to'), soundex('need'), soundex('more')))
('some helpful cases to consider', CONCAT_WS(' ', soundex('some'), soundex('helpful'), soundex('cases'), soundex('to'), soundex('consider')))

select * from with_soundex where match(soundex) against (soundex('test'));
+----+---------------------+---------------------+
| id | original            | soundex             |
+----+---------------------+---------------------+
|  1 | add some test cases | A300 S500 T230 C000 | 
|  2 | this is some text   | T200 I200 S500 T230 | 
|  3 | one more test case  | O500 M600 T230 C000 | 
+----+---------------------+---------------------+

select * from with_soundex where match(soundex) against (CONCAT_WS(' ', soundex('test'), soundex('some')));
+----+--------------------------------+---------------------------+
| id | original                       | soundex                   |
+----+--------------------------------+---------------------------+
|  1 | add some test cases            | A300 S500 T230 C000       | 
|  2 | this is some text              | T200 I200 S500 T230       | 
|  3 | one more test case             | O500 M600 T230 C000       | 
|  7 | some helpful cases to consider | S500 H414 C000 T000 C5236 | 
+----+--------------------------------+---------------------------+

これにより、インデックスを最大限に活用しながら (soundex アルゴの制限内で) かなり良い結果が得られます (クエリ LIKE '%foo' では、テーブル内のすべての行をスキャンする必要があります)。

フレーズ全体ではなく、単語ごとに soundex を実行することの重要性に注意してください。SQL に実行させるのではなく、単語ごとに独自のバージョンの soundex を実行することもできますが、その場合は、アルゴリズムに違いがある場合に備えて、格納と取得の両方で実行するようにしてください (たとえば、MySQL のアルゴリズムは制限されません)。自体を標準の4 文字に)

于 2009-12-16T08:29:57.243 に答える
1

独自のソリューションを作成するのではなく、単純な既存のソリューションを探している場合は、チェックアウトしてください

于 2009-12-14T11:56:29.220 に答える
0

Soundex には、あいまい検索を処理するための制限があります。より優れた機能は、UDF を使用して MySQL に統合できる編集距離です。Linux 上の MySQL の C++ 実装については、http://flamingo.ics.uci.edu/toolkit/を確認してください。

于 2013-03-14T16:03:56.943 に答える
0

mysqlにはSOUNDEXという関数があります。映画のタイトルを検索する場合:

select * from movie where soundex(title) = soundex( 'the title' );

もちろん、映画やあらすじなど、テキストで検索してもうまくいきません。


Soundex は比較的単純なアルゴリズムです。また、適用可能なレベルですべてを処理することもできます。その方が簡単かもしれません。

  • テキストが保存されたら、それをトークン化し、すべての単語にsoundexを適用します
  • 元のテキストと soundex バージョンを 2 つの列に保存する
  • 検索するときは、アプリで soundex を計算します。LIKEレベルを使用してから、db レベルで正規を使用します。
于 2009-12-14T08:40:22.070 に答える