全文検索とキーワードスコアリング方式の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サービスのリモートログイン操作を開始します

推薦する

ページキャッシュを無効にするいくつかの方法を共有する

本日、開発中に、顧客からページをキャッシュしないように要求される方法に遭遇しました。調べたところ、ペ...

Vue ルーティングフォールバックに最適なソリューション (vue-route-manager)

目次ルーティングマネージャー背景はじめる問題を解決する方法要約するルーティングマネージャー各ジャンプ...

Linux仮想マシンをWiFiに接続する方法

生活の中で、インターネットはどこにでもあります。インターネットを通じてゲームをしたり、テレビ番組を見...

最適なウェブページ幅とその互換性のある実装方法

1. Web ページをデザインするときに、幅を決定するのは非常に面倒な作業です。 jb51.net ...

mysql5.7.24 バージョンのインストール手順と解凍時に発生した問題の概要

1. ダウンロード参考: 2. D:\MySQL\mysql-5.7.24 などの固定の場所に解凍し...

MySQLはPartition関数を使用して水平分割戦略を実装します。

目次1件のレビュー2 水平分割の5つの戦略2.1 ハッシュ2.2 範囲2.3. キー2.4. リスト...

時間範囲効果を実現するためのJavaScript

この記事では、時間範囲効果を実現するためのJavaScriptの具体的なコードを参考までに紹介します...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

Ubuntu 16.04/18.04 に Pycharm と Ipython をインストールするチュートリアル

Ubuntu 18.04の場合1. sudo apt install python 。コマンドライン...

MySQL 完全折りたたみクエリ正規マッチングの詳細な説明

概要前の章では、クエリのフィルター条件について学習しました。MySQL では、like % ワイルド...

Nginx がフロントエンド リソースへのクロスドメイン アクセスの問題をどのように解決するかの詳細な説明

フロントエンドのクロスドメイン問題に2日間近く悩まされましたが、ようやくngnxを使って解決したので...

ブラウザが登録できるイベントの概要

HTML イベント リスト一般イベント: onClick HTML: マウスクリックイベント。主にオ...

React ページ ターナーの実装 (フロント エンドとバックエンドを含む)

目次フロントエンド上記のアイデアに従って、ページめくり機能を設計して記述します。バックエンド(Jav...

JavaScript ECharts の使用方法の説明

以前、プロジェクトを行う際に ECharts を使用しました。今日はそれをメモとして整理し、より多く...

テーブルの最大幅と最小幅を設定する際の互換性の問題と解決策の詳細な説明

テーブル内の min-width と max-width プロパティの設定 <テーブル>...