<< man.ChinaUnix.net に戻る
バージョン 4.1.0-alpha の MySQL リファレンス マニュアル
------ - ------------------------------------------------- - ----------------------
6.8 MySQL 全文検索
3.23.23 以降、MySQL はサポートを開始します全文インデックス作成と検索。 MySQL のフルテキスト インデックスは FULLTEXT 型のインデックスです。 FULLTEXT インデックスは MyISAM テーブルで使用され、CREATE TABLE 時またはその後に ALTER TABLE または CREATE INDEX を使用して CHAR、VARCHAR、または TEXT カラムに作成できます。大規模なデータベースの場合、FULLTEXT インデックスを使用せずにテーブルにデータをロードし、ALTER TABLE (または CREATE INDEX) を使用してインデックスを作成すると非常に高速になります。すでに FULLTEXT インデックスがあるテーブルにデータをロードすると、非常に時間がかかります。
全文検索は MATCH() 関数によって完了します。
mysql> CREATE TABLE 記事 (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY、
-> title VARCHAR(200)、
-> body TEXT、
-> FULLTEXT (title,body)
-> );
クエリは 0 行に影響を受けました (0.00 秒)
mysql> 値を挿入します
-> NULL,'MySQL チュートリアル', 'DBMS は DataBase の略です ...'),
-> (NULL,'MySQL を効率的に使用する方法', '経験した後...'),
-> (NULL,'MySQL の最適化','このチュートリアルでは ...'),
-> (NULL,'1001 MySQL のトリック','1. mysqld を root として実行しないでください。 ...'),
-> (NULL,'MySQL と YourSQL', '次のデータベース比較では ...'),
-> (NULL,'MySQL セキュリティ', '正しく設定されました。MySQL ...');
クエリ OK、6 行が影響を受けました (0.00 秒)
レコード: 6 重複: 0 警告: 0
mysql> SELECT * FROM 記事
-> WHERE MATCH (title,body) AGAINST ('データベース') ---- -------- ------- -----------------------------------
| タイトル ---------- -------------------------------------- ---------- ---
| 5 | MySQL と YourSQL の比較 ...
| ---------------- ------------------------ ---------- --------
セット内の 2 行 (0.00 秒)
関数 MATCH() は、テキスト セット (FULLTEXT インデックスに含まれる 1 つ以上の列の列セット) を比較します。文字列の自然言語検索。検索文字列は AGAINST() の引数として与えられます。検索は、大文字と小文字を区別せずに実行されます。テーブル内の各行について、MATCH() は相関値を返します。つまり、検索文字列と MATCH() リストで指定された列のレコード行のテキストとの間の類似性の尺度です。
MATCH() が WHERE 句で使用される場合 (上記の例を参照)、返された行は関連性の高いものから低いものの順に自動的に並べ替えられます。相関値は非負の浮動小数点数です。相関関係がゼロとは、類似性がないことを意味します。関連性は、行内の単語の数、行内の固有の単語の数、セット内の単語の合計数、および特定の単語を含むドキュメント (行) の数に基づいて計算されます。
論理パターン検索も実行できます。これについては、次のセクションで説明します。
前の例は、関数 MATCH() の使用に関するいくつかの基本的な手順です。行は類似性の高い順に返されます。
次の例は、明示的な類似度値を取得する方法を示します。 WHERE 句も ORDER BY 句も存在しない場合、返される行は並べ替えられません。
mysql> SELECT id,MATCH (title,body) AGAINST ('チュートリアル')
---- ----------------- ------------------------
| ID (タイトル、本文) と一致します ('チュートリアル') | -------------------------------------------------- -
| -----------
セット内の 6 行 (0.00 秒)
以下の例はもう少し複雑です。クエリは類似度を返しますが、類似度の降順で行を返します。この結果を達成するには、MATCH() を 2 回指定する必要があります。 MySQL オプティマイザは同じ MATCH() 呼び出しを 2 回認識し、全文検索コードを 1 回だけ呼び出すため、追加のオーバーヘッドは発生しません。
mysql> SELECT id, body, MATCH (title,body) AGAINST
-> ('MySQL を root として実行することによるセキュリティへの影響') AS スコア
-> title,body) AGAINST
-> ('MySQL を root として実行することによるセキュリティへの影響') ---- -------------------- ------------------ ---------------
| 本文 ---------- -------------------------------------- -----
| 1. mysqld を root として実行しないでください。 | 1.5055546709332 |
| ------------------------------------------------ -- ---
セット内の 2 行 (0.00 秒)
MySQL は非常に単純なパーサーを使用してテキストを単語に分割します。 「単語」とは、テキスト、データ、「'」および「_」で構成される一連の文字です。ストップワード リストにある「単語」、または短すぎる (3 文字以下) 場合は無視されます。
セットおよびクエリ内の各適切な単語は、セットおよびクエリ内の重要度に従って測定されます。このようにして、複数の文書に出現する単語の重みは低くなります (おそらく重みがゼロになることもあります)。これは、この特定のセットでは意味論的な値が低いためです。それ以外の場合、単語が小さい場合は重みが高くなります。次に、単語の重みを組み合わせて、レコード行の類似性を計算します。
このようなテクニックは大規模なセットでうまく機能します (実際、慎重に調和させられます)。非常に小さなテーブルの場合、単語の分類はその意味論的な値を適切に反映せず、場合によってはこのモデルが奇妙な結果を生み出す可能性があります。
mysql> SELECT * FROM Articles WHERE MATCH (title,body) AGAINST ('MySQL');
空のセット (0.00 秒)
上記の例では、検索語は MySQL ですしかし、単語がレコード行の半分以上に出現するため、結果は得られませんでした。したがって、これは事実上ストップワード (つまり、意味値がゼロの単語) として扱われます。これは理想的な動作です。自然言語クエリは 1 GB のテーブルから 2 行おきに返すべきではありません。
表内の行の半分に一致する単語は、関連するドキュメントが見つからない可能性があります。実際、無関係な文書が多数見つかる可能性があります。検索エンジンを通じてインターネット上で何かを検索しようとすると、このようなことが常に起こることは誰もが知っています。このため、この特定のデータセットでは、そのような行は低いセマンティック値に設定されます。
4.0.1 以降、MySQL は IN BOOLEAN MODE 修飾子を使用して論理全文検索を実行することもできます。
mysql> SELECT * FROM 記事 WHERE MATCH (title,body)
-> AGAINST (' MySQL -YourSQL' IN BOOLEAN MODE) ---- ------ -------------------------------------------------- --- ------------
| タイトル ---------- ---- -----------------
| 1 | DBMS は、DataBase の略です。 | 2 | MySQL を効率的に使用する方法|
| このチュートリアルでは、mysqld を root として実行しないでください。 >| 6 | MySQL のセキュリティ | 適切に設定されている場合、... 🎜 ----- ------------------ ------------------
このクエリは次の結果を返しますMySQL という単語を含むすべての行 (注: 50% のしきい値は使用されません)、ただし YourSQL という単語は含まれません。論理パターン検索では、類似した値の降順で行が自動的に並べ替えられないことに注意してください。上記の結果からわかるように、最も高い類似値 (MySQL を 2 回含む値) は最初ではなく最後にリストされます。論理全文検索は FULLTEXT インデックスがなくても機能しますが、速度は遅くなります。
論理全文検索では、次の演算子がサポートされています。
先頭のプラス記号は、返される各レコード行に単語が出現する必要があることを示します。
-
先頭のマイナス記号は、返される各レコード行に単語が出現してはならないことを示します。
デフォルト (プラス記号もマイナス記号も指定されていない場合) の単語はオプションですが、それを含む行は上位にランクされます。これは、IN BOOLEAN MODE 修飾子を使用しない MATCH() ... AGAINST() の動作を模倣します。
< >
これら 2 つの演算子は、単語の類似度値の基本値を変更するために使用されます。 < 演算子は基本値を減少させ、> 演算子はそれを増加させます。以下の例を参照してください。
( )
括弧は部分式内の単語をグループ化するために使用されます。
~
先頭の否定記号は否定演算子のように機能し、行の類似性単語が負の基本値を持つようになります。ノイズの多い単語にラベルを付けるのに便利です。このような単語を含むレコードはランクが低くなりますが、- 演算子が使用できるため、完全に除外されるわけではありません。
*
アスタリスクは切り捨て演算子です。他の演算子とは異なり、単語の前ではなく単語に追加する必要があります。
「二重引用符で囲まれた
フレーズ」は、そのフレーズを含む行のみに一致します (文字通り、入力されたかのように)。
ここにいくつかの例があります:
アップル バナナ
上記の単語の少なくとも 1 つを含む行を検索
アップル ジュース
... 両方の単語が含まれます
アップル マッキントッシュ
...単語「apple」が含まれていますが、「macintosh」も含まれている場合は上位にランクされます
apple -macintosh
...「apple」は含まれますが、「macintosh」は含まれません
apple (>pie
apple*
... "apple"、"apples"、"applesauce"、および "applet" が含まれます
"some word"
.. を含むことができます。
6.8.1 フルテキストの制限
MATCH() 関数のすべてのパラメータは、同じテーブルの列からのものである必要があり、同じ FULLTEXT インデックスの一部である必要があります。 MATCH() はブール モードです。
MATCH() 列リストは、 MATCH() が IN BOOLEAN MODE でない限り、テーブルの FULLTEXT インデックスで定義された列リストと正確に一致する必要があります。
AGAINST() のパラメータは定数文字列である必要があります。
6.8.2 MySQL 全文検索の微調整
残念ながら、全文検索にはユーザーが調整できるパラメータがまだほとんどありませんが、いくつか追加すると TODO の上位にランクされます。 MySQL ソース ディストリビューションがある場合 (セクション 2.3 MySQL ソース ディストリビューションのインストールを参照)、全文検索をより詳細に制御できます。
全文検索は最良の検索結果が得られるように慎重に調整されていることに注意してください。デフォルトの動作を変更すると、ほとんどの場合、検索結果が悪化するだけです。何をしようとしているのか理解していない限り、MySQL ソース コードを変更しないでください。
インデックス付きワードの最小長は、MySQL 変数 ft_min_word_len で指定されます。セクション 4.5.6.4 変数の表示を参照してください。これを希望の値に変更し、FULLTEXT インデックスを再構築します。 (この変数は MySQL 4.0 以降でのみサポートされます)
ストップワード リストは、ft_stopword_file 変数で指定されたファイルから読み取ることができます。セクション 4.5.6.4 変数の表示を参照してください。ストップワード リストを変更した後、FULLTEXT インデックスを再構築します。 (この変数は MySQL 4.0.10 以降でのみサポートされます)
50% しきい値の選択は、選択した特定の測定モードによって決まります。これを無効にするには、`myisam/ftdefs.h' ファイル内の次の行を変更します:
#define GWS_IN_USE GWS_PROB
を
#define GWS_IN_USE GWS_FREQ
に変更し、再コンパイルします。 MySQL。この場合、インデックスを再構築する必要はありません。注: これを使用すると、MATCH() に十分な類似性の値を提供する MySQL の機能が大幅に低下します。このような公開ワードを本当に検索する必要がある場合は、代わりに、50% のしきい値を無視する IN BOOLEAN MODE 検索を使用することをお勧めします。
検索エンジンの管理者は、論理全文検索に使用される演算子を変更したい場合があります。これらは変数 ft_boolean_syntax によって定義されます。セクション 4.5.6.4 変数の表示を参照してください。ただし、この変数は読み取り専用であり、その値は `myisam/ft_static.c' に設定されます。
これらの変更では、FULLTEXT インデックスを再構築する必要があります。MyISAM テーブルの場合、インデックス ファイルを再構築する最も簡単な方法は次のとおりです。 🎜>6.8.3 全文検索 TODO
FULLTEXT インデックスに対するすべての操作を高速化します
近接演算子
「常にインデックスを付ける単語」のサポート。 「C」、「AS/400」、「TCP/IP」など、ユーザーが単語として扱いたい任意の文字列を指定できます。
MERGE テーブルでの全文検索をサポート
多バイト文字のサポート
データの言語に応じてストップワード リストを作成します
ステミング (もちろんデータの言語に依存します)
ユーザーが指定できる汎用の UDF プリパーサー
スキーマをより柔軟にします。 (ALTER TABLE の CREATE/FULLTEXT により、いくつかの調整可能なパラメーターが追加されます)