全文検索とキーワードスコアリング方式のMySQL実装例

全文検索とキーワードスコアリング方式のMySQL実装例

1. はじめに

今日、同僚から、MySQL を使用して ElasticSearch に似た全文検索機能を実装し、検索キーワードにスコアを付ける方法を尋ねられました。すぐに私の心の中に疑問が浮かびました。なぜesを使わないのですか?シンプルで使いやすく、高速です。しかし、データ量が多くなく、クライアントから与えられた時間も非常に限られており、esを構築する時間がないとのことなので、MySQLの全文検索機能を見てみましょう!

MySQL バージョン 5.7.6 以降では、中国語、日本語、韓国語の単語分割をサポートする ngram フルテキスト パーサーが組み込まれています。 MySQL 5.7.6 より前のバージョンでは、フルテキスト インデックスは英語のフルテキスト インデックスのみをサポートしており、中国語のフルテキスト インデックスはサポートしていませんでした。単語セグメンターを使用して中国語の段落を単語に前処理し、データベースに保存する必要がありました。この記事は、Mysql 5.7.6、InnoDB データベース エンジンを使用してテストされました。 mysql 全文検索

2. 全文パーサーngram

ngram は、テキスト内の n 個の連続した単語のシーケンスです。 ngram フルテキスト パーサーは、テキストを単語に分割できます。各単語は n 個の連続した単語のシーケンスです。
たとえば、ngram フルテキスト パーサーを使用して「hello world」をトークン化します。

n=1: 「あなた」、「良い」、「世界」、「世界」 
n=2: 「こんにちは」、「良い世界」、「世界」 
n=3: 「こんにちは世界」、「良い世界」 
n=4: 「こんにちは世界」

MySQL はグローバル変数 ngram_token_size を使用して、ngram 内の n のサイズを設定します。値の範囲は 1 ~ 10 で、デフォルト値は 2 です。通常、ngram_token_size はクエリされる単語の最小数に設定されます。単語のみを検索する必要がある場合は、ngram_token_size を 1 に設定します。デフォルト値 2 の場合、単語 1 つを検索しても結果は返されません。中国語の単語は少なくとも 2 つの文字で構成されているため、デフォルト値の 2 が推奨されます。

MySQL のデフォルトの ngram_token_size を見てみましょう。

'ngram_token_size' のような変数を表示する

ngram_token_size 変数を設定するには、次の 2 つの方法があります。

1. mysqldコマンドの起動時に指定する

mysqld --ngram_token_size=2

2. MySQL設定ファイルを変更する

[mysqld] 
nグラムトークンサイズ=2

3. 全文索引

ドキュメントデータを例にとると、新しいデータテーブル t_wenshu が作成され、ドキュメントコンテンツフィールドにフルテキストインデックスが作成され、100,000 件のテストデータがインポートされます。

1. テーブルを構築するときにフルテキストインデックスを作成する

テーブル `t_wenshu` を作成します (
 `province` varchar(255) デフォルト NULL,
 `caseclass` varchar(255) デフォルト NULL,
 `casenumber` varchar(255) デフォルト NULL,
 `caseid` varchar(255) デフォルト NULL,
 `types` varchar(255) デフォルト NULL,
 `title` varchar(255) デフォルト NULL,
 `content` 長文、
 `updatetime` varchar(255) デフォルト NULL,
 フルテキストキー `content` (`content`) とパーサー `ngram`
)ENGINE=InnoDB デフォルト文字セット=utf8;

2. テーブル変更方法

ALTER TABLE t_wenshu に、PARSER ngram を使用して FULLTEXT INDEX content_index (content) を追加します。

3. インデックス作成メソッドを通じて

PARSER ngram を使用して、t_wenshu (content) にフルテキスト インデックス content_index を作成します。

4. 検索モード

自然言語検索

(自然言語モード) 自然言語モードは、MySQL のデフォルトの全文検索モードです。自然言語モードでは演算子を使用できず、キーワードが表示される必要がある、または表示されない必要があるなどの複雑なクエリを指定することはできません。

ブール検索

(ブール モード) 一致する行の半分以上に出現する単語を除外します。たとえば、すべての行に「this」という単語が含まれている場合、「this」で検索しても結果は見つかりません。これは、レコードの数が多い場合に非常に便利です。データベースは、すべての行を検索しても意味がないと判断するためです。この場合、「this」はほぼストップワードと見なされます。ブール検索モードで演算子を使用すると、キーワードの出現または不出現の指定、キーワードの重みが高いか低いかの指定など、複雑なクエリをサポートできます。

● ブールモードの機能:
一致基準が 50% を超える行は削除しないでください。
関連性の逆順に自動的に並べ替えることはありません。
FULLTEXT インデックスなしでフィールドを検索することも可能ですが、非常に遅くなります。
·最大および最小の文字列を制限します。
· ストップワードを適用します。

● 検索構文ルール:
+ 存在する必要があります (このキーワードを含まないデータ エントリは無視されます)。
- 許可されません (指定されたキーワードを除き、そのキーワードを含むすべてのエントリは無視されます)。
> この一致するデータの重みを増やします。
< 一致するデータの重みを減らします。
~ は相関関係を正から負に変えることにより、その単語があると相関関係が減少することを示します (ただし、その単語を除外する like は除きます)。順位が下がり、重みが低くなるだけです。
* ワイルドカードは、先頭に配置される他の構文とは異なり、文字列の後に配置する必要があります。
" " 二重引用符を使用して文を囲むと、元の文と完全に一致する必要があり、文字を分離できないことを示します。

クエリ拡張検索

注意: (クエリ拡張あり) クエリ拡張により無関係なクエリが多数生成される可能性があるため、注意して使用してください。

5. 検索クエリ

1) コンテンツに「盗難」を含むレコードをクエリします。クエリステートメントは次のとおりです。

t_wenshu から caseid、content、MATCH (content) AGAINST ('Theft') をスコアとして選択します。MATCH (content) AGAINST ('Theft' IN NATURAL LANGUAGE MODE)

2) コンテンツに「挑交惹事」を含むレコードを検索します。クエリステートメントは次のとおりです。

select caseid,content, MATCH (content) AGAINST ('寻怨惹事') as score from t_wenshu where MATCH (content) AGAINST ('寻怨惹事' IN NATURAL LANGUAGE MODE);

3) 単一の漢字、コンテンツに「我」を含むレコードを検索する場合、クエリステートメントは次のとおりです。

t_wenshu から caseid、content、MATCH ( content) AGAINST ('我') をスコアとして選択します。ここで、MATCH ( content) AGAINST ('我' IN NATURAL LANGUAGE MODE) ;

注: グローバル変数 ngram_token_size の値が 2 に設定されているためです。単一の中国語文字をクエリする場合は、構成ファイル my.ini で ngram_token_size = 1 を変更し、mysqld サービスを再起動する必要があります。ここではこれを試しません。

4) クエリフィールドの内容には、次のように「危険運転」と「喧嘩やトラブルを起こす」が含まれています。

select caseid,content, MATCH (content) AGAINST ('+危険運転+けんかを売ってトラブルを起こす') as score from t_wenshu where MATCH (content) AGAINST ('+危険運転+けんかを売ってトラブルを起こす' IN BOOLEAN MODE);

5) クエリフィールドの内容には、「危険運転」は含まれていますが、「喧嘩を売ったりトラブルを起こしたりすること」は含まれていません。

select caseid,content, MATCH (content) AGAINST ('+危険運転-喧嘩を売ってトラブルを起こす') as score from t_wenshu where MATCH (content) AGAINST ('+危険運転-喧嘩を売ってトラブルを起こす' IN BOOLEAN MODE);

6) クエリフィールドの内容には、次のように「危険運転」または「口論やトラブルを起こす」が含まれます。

select caseid,content, MATCH (content) AGAINST ('危険運転とトラブル誘発') as score from t_wenshu where MATCH (content) AGAINST ('危険運転とトラブル誘発' IN BOOLEAN MODE);

VI. 結論

1) MySQL フルテキスト インデックスを使用する前に、各バージョンのサポート状況を確認してください。

2) 全文インデックスは like + % よりも N 倍高速ですが、精度の問題が発生する可能性があります。

3) 大量のデータを完全にインデックス化する必要がある場合は、まずデータを追加してからインデックスを作成することをお勧めします。

4) 中国語の場合、MySQL 5.7.6 以降のバージョン、または Sphinx や Lucene などのサードパーティ製プラグインを使用できます。

5) MATCH() 関数で使用されるフィールド名は、フルテキスト インデックスの作成時に指定されたフィールド名と一致している必要があり、同じテーブルのフィールドのみにすることができ、テーブルをまたぐことはできません。

これで、MySQL の全文検索とキーワード スコアリングに関するこの記事は終了です。MySQL の全文検索とキーワード スコアリングに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL 5.7 での中国語全文検索の詳細な分析
  • MySQL フルテキスト検索の中国語ソリューションとサンプルコード
  • MySQL全文検索の使用例
  • MySQL 5.7.25 全文検索チュートリアル

<<:  JavaScript における一般的な配列操作

>>:  UbuntuはSSHサービスのリモートログイン操作を開始します

推薦する

スケーラブルな列の完全な例を実現するための Ant 設計 Vue テーブル

ant-design-vue テーブルのスケーラブルな列の問題に対する完璧なソリューション。固定列と...

仮想マシンの複製に関するVirtual Boxチュートリアル図

VMに慣れた後、BOXに切り替えるのは少し異なります。たとえば、コピーネットワークカードを2枚使って...

CSS の高さの崩壊問題の解決

1. 崩壊度が高いドキュメント フローでは、親要素の高さはデフォルトで子要素によって拡張されます。つ...

背景のグラデーションと自動フルスクリーンを実現するCSSコード

背景グラデーションと自動フルスクリーンに関する CSS の問題編集長は CSS の開発中に致命的な問...

Alibaba Cloud Centos 7.5 に MySQL をインストールするチュートリアル

CentOS 7 の yum ソースには、MySQL を正常にインストールするための mysql-s...

配列をフラット化する 5 つの JavaScript の方法

目次1. 配列の平坦化の概念2. 実装1. 減らす2. toString と split 3. 結合...

CSS のインライン スタイルに変換するソリューション (css-inline)

シーンについて話すメールを送信サードパーティのウェブサイトにHTMLを埋め込む他の編集者の記事をコピ...

数十行のjsを使用してクールなキャンバスインタラクティブ効果を実現する方法を教えます

目次1. 円を描く2. マウスで動かした円3. マウスでドラッグした粒子4. カラーグラデーション粒...

Dockerコンテナでルート権限を取得する方法

まず、コンテナが稼働している必要がありますコンテナのCONTAINER IDは、sudo docke...

Xtrabackup を使用した MySQL バックアップ プロセスの詳細な説明

目次01 背景02 はじめに03 ワークフロー04 いくつかの質問05 ファイルをバックアップする0...

CentOS 7でsambaを使用してフォルダーを共有するための完全な手順

序文Samba は、サーバー プログラムとクライアント プログラムで構成され、Linux システム上...

MySQL データベース シェル import_table データ インポート

目次MySQL Shell import_table データのインポート1. import_tabl...

Linux で MySQL をインストールする簡単な方法

Linux に MySQL をインストールする方法をオンラインで検索すると、多くの方法が表示されまし...

ウォーターフォールフローレイアウトを実装する3つの方法

序文今日、Xianyuを閲覧していたとき、各行の高さが同じではないことに気付きました。調べてみると、...

MacBook 向け Python 3.7 インストール チュートリアル

MacBookにpython3.7.0をインストールする詳細な手順は、参考までに記録されています。具...