内容へ移動
Ground Sunlight
Windowsで作る - PHPプログラミングの開発環境
ユーザ用ツール
ログイン
サイト用ツール
検索
ツール
文書の表示
以前のリビジョン
バックリンク
最近の変更
メディアマネージャー
サイトマップ
ログイン
>
最近の変更
メディアマネージャー
サイトマップ
トレース:
mroonga:10.7:config
この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。
====== Mroonga9.12 全文検索の構成 ====== Version 9.12 (MariaDB 10.4.12) --- //[[http://www.y2sunlight.com|y2sunlight]] 2020-11-06// [[mroonga:top|Mroonga に戻る]] 関連記事 * [[mroonga:10.7:install|Mroonga9.12 インストール]] * [[mroonga:10.7:tutorial|Mroonga9.12 検索チュートリアル]] * Mroonga9.12 全文検索の構成 リンク * https://mroonga.org/ja/docs/tutorial.html --- Mroongaチュートリアル * https://qiita.com/mogulla3/items/23aaffbe29c4e600876d -- 検索エンジンまわりでの重要語リスト。全文検索の基礎用語が端的に纏まっています。初学者の方はまずこれをご一読下さい。 * https://blog.createfield.com/entry/2014/10/29/084941 --- Mroongaのテーブル設計について分かり易く纏まっています。 本編では、Mroonga公式サイトの[[https://mroonga.org/ja/docs/tutorial.html|チュートリアル]]を参考にしてMroongaの全文検索の構成について、トークナイザー(Tokenizer)、ノーマラーザー(Normalizer)、トークンフィルタ―(Token Filter) について説明したいと思います。 \\ ----- ===== 全文検索の仕組み ===== 全文検索とは、複数の文書から特定の文字列を検索することを意味し、ここでは特に「インデックス(索引)型」の全文検索を指すものとします。インデックス型の全文検索は大きく分けて次の2つの部分から構成されています。 * 検索対象の文書登録 * キワードによる文書検索 Mroongaにおける文書検索については本編の「[[mroonga:10.7:tutorial|検索チュートリアル]]」を参照して下さい。本章では、文書登録について説明します。全文検索における文書登録はおおよそ次の流れで行われます: - ノーマライズ (正規化) - トーカナイズ (トークン化) - トークンフィルタリング - トークンを索引に登録する Mroongaでは、これらの構成のほとんどをSQLのcreate文によって行います。以下ではノーマライズ、トーカナイズ、トークンフィルターについて説明します。 \\ ===== ノーマライズ ===== ノーマライズ(Normalize)とは、日本語の場合、大文字と小文字、全角と半角、カタカナとひらがななどを統一して正規化する処理を指します。ノーマライズはトーカナイズの前処理として行われます。以下に正規化の例を挙げておきます。 ^前^後^正規化^ |Apple|APPLE|小文字 <nowiki>=></nowiki> 大文字| |ブラック|ブラック|半角 <nowiki>=></nowiki> 全角| |リンゴ|りんご|カタカナ <nowiki>=></nowiki> ひらがな| 結論から先に言うと、ノーマライザーとしては [[https://groonga.org/ja/docs/reference/normalizers/normalizer_auto.html|NormalizerAuto]] を使用すべきです。以下、チュートリアルに従ってその理由を説明します。 \\ ==== 日本語の文字セットと照合順序 ==== 日本語の文字セットは UTF8 を使用することを前提にします。UTF8 の文字コードは次の2種類があります。 * ''utf8'' --- 文字ごとに最大3バイトを使用しBMP(基本多言語面)のみを含みます。 * ''utf8mb4'' --- 文字ごとに最大4バイトを使用しBMP(基本多言語面)に加え補助文字をサポートしています。 utf8は、''utf8mb3''と呼ばれることもあります。utf8mb4の補助文字としては[[https://ja.wikipedia.org/wiki/%E6%90%BA%E5%B8%AF%E9%9B%BB%E8%A9%B1%E3%81%AE%E7%B5%B5%E6%96%87%E5%AD%97|絵文字]]が有名で、au、docomo、SoftBankなどそれぞれの機種によって絵文字がサポートされています。 UTF8 の代表的な照合順序には、以下のものがあります。 * utf8_bin --- バイナリ照合。文字コードが一致した場合のみマッチ。 * utf8_general_ci --- 大文字・小文字を区別しない(半角同士 及び 全角同士) * utf8_unicode_ci --- 大文字・小文字、半角・全角、ひらがな・カタカナ、拗音/促音/濁音/半濁音と清音を区別しない * utf8mb4_general_ci --- utf8_general_ci と同じ。 * utf8mb4_unicode_ci --- utf8_unicode_ci と同じ。 > ''_bin'' は ''binary''、''_ci'' は ''case insensitive''(大文字・小文字を区別しない) の略として照合順序の名称に使用される接尾語です。 \\ ==== デフォルトのノーマライザー ==== Mroongaは、テーブルの照合順序に応じたノーマライザーを使用します。 ^照合順序^ノーマライザー^ |utf8_bin|指定無し| |utf8_general_ci|NormalizerMySQLGeneralCI| |utf8mb4_general_ci|:::| |utf8_unicode_ci|NormalizerMySQLUnicodeCI| |utf8mb4_unicode_ci|:::| \\ ==== NormalizerMySQLUnicodeCI ==== 以下の例では、utf8_unicode_ci の照合順序を指定することによって、デフォルトのノーマライザー(NormalizerMySQLUnicodeCI)を使用しています。 例 <code sql> CREATE TABLE diaries_ci ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(255), FULLTEXT INDEX (content) ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT INTO diaries_ci (content) VALUES ("びょういんの朝食はブラックコーヒーとパンです。"); </code> どのようにノーマライズされるかは、Groonga の ''normalize'' コマンドで確認できます。 <code sql> SELECT mroonga_command('normalize NormalizerMySQLUnicodeCI "びょういんの朝食はブラックコーヒーとパンです。"'); </code> 結果は以下のようになります: <code> {"normalized":"ひよういんの朝食はふらつくこーひーとはんてす。","types":[],"checks":[]} </code> 拗音、促音、濁音、半濁音が全て清音に変換されています。従って以下の検索は全てヒットします。 <code sql> SELECT * FROM diaries_ci WHERE MATCH (content) AGAINST ("+びよういん" IN BOOLEAN MODE); SELECT * FROM diaries_ci WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE); SELECT * FROM diaries_ci WHERE MATCH (content) AGAINST ("+はん" IN BOOLEAN MODE); </code> また、utf8_unicode_ci では半角・全角を区別しないので以下の検索もヒットします。 <code sql> SELECT * FROM diaries_ci WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE); </code> 半角・全角の区別は良いとしても、「病院」と「美容院」、「ふらつく」と「ブラック」など拗音、促音、濁音、半濁音が清音と同じになるのは、言語的に「音」も「意味」も違うので問題が残る結果となっています。 \\ ==== ノーマライザーの指定 ==== CREATE TABLE 文の中でノーマライザーを指定するには、''COMMENT'' を使用した以下の構文に従います: <code sql> FULLTEXT [INDEX] [インデックス名] (カラム1,...) COMMENT 'normalizer "ノーマライザー名"' </code> Mrrongaに組み込まれているノーマライザーについては、以下のGroongaのドキュメントを参照して下さい: * https://groonga.org/ja/docs/reference/normalizers.html \\ ==== NormalizerAuto ==== 以下は、ノーマラーザーとして ''NormalizerAuto'' を使用した例です: <code sql> CREATE TABLE diaries_auto ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(255), FULLTEXT INDEX (content) COMMENT 'normalizer "NormalizerAuto"' ) Engine=Mroonga DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; INSERT INTO diaries_auto (content) VALUES ("びょういんの朝食はブラックコーヒーとパンです。"); </code> どのようにノーマライズされるかは、Groonga の ''normalize'' コマンドで確認できます。 <code sql> SELECT mroonga_command('normalize NormalizerAuto "びょういんの朝食はブラックコーヒーとパンです。"'); </code> 結果は以下のようになります: <code> {"normalized":"びょういんの朝食はブラックコーヒーとパンです。","types":[],"checks":[]} </code> 拗音、促音、濁音、半濁音はそのまま保存さえれて清音のままです。従って、''NormalizerMySQLUnicodeCI'' とは異なり以下の検索は全てヒットしません。 <code sql> SELECT * FROM diaries_auto WHERE MATCH (content) AGAINST ("+びよういん" IN BOOLEAN MODE); SELECT * FROM diaries_auto WHERE MATCH (content) AGAINST ("+ふらつく" IN BOOLEAN MODE); SELECT * FROM diaries_auto WHERE MATCH (content) AGAINST ("+はん" IN BOOLEAN MODE); </code> 但し、''NormalizerAuto'' は半角・全角を区別しないので以下の検索はヒットします。 <code sql> SELECT * FROM diaries_auto WHERE MATCH (content) AGAINST ("+ブラック" IN BOOLEAN MODE); </code> このように、''NormalizerAuto'' では、半角・全角の区別をしないだけで、拗音、促音、濁音、半濁音と清音は区別されており、''NormalizerMySQLUnicodeCI'' よりは自然な検索結果になっているのが分かります。 ''NormalizerAuto'' についての詳細は以下の Groonga のドキュメントをご覧ください: * https://groonga.org/ja/docs/reference/normalizers/normalizer_auto.html \\ ===== トークナイザー(パーサ) ===== CREATE TABLE 文の中でトークナイザーを指定するには、COMMENT を使用した以下の構文に従います: <code sql> FULLTEXT [INDEX] [インデックス名] (カラム1,...) COMMENT 'tokenizer "トークナイザー名"' </code> トークナイザーは、MySQL(mariaDB) ではパーサと呼ばれています。MySQLでは、パーサの指定に別の構文( ''WITH PARSER'' )がありますが、Mroongaでは、利便性のために上記の構文が採用されています。 トークナイザーに指定できる主なものを以下に示します。全てのリストは、Mroongaの[[https://mroonga.org/ja/docs/tutorial/storage.html#how-to-specify-the-parser-for-full-text-search|ドキュメント]]を参照して下さい。 ^トークナイザー^説明^ |none|トークナイズしません。| |TokenDelimit|空白区切りでトークナイズします。| |TokenRegexp|正規表現検索をサポートするトークナイザーです。| |TokenUnigram|ユニグラム(1-Gram)でトークナイズします。| |TokenBigram|バイグラム(2-Gram)でトークナイズします。| |TokenTrigram|トリグラム(3-Gram)でトークナイズします。| |TokenMecab|MeCabを用いてトークナイズします。| デフォルトのパーサは以下で確認できます: <code sql> SHOW VARIABLES LIKE 'mroonga_default_tokenizer'; </code> デフォルトのトークナイザーはビルド時や ''my.cnf'' ( Windowsでは''my.ini'' )で指定できます。このオプションを指定しないときは ''TokenBigram'' になります。my.cnf では以下のようにして指定します。 my.cnf: <code ini> [mysqld] mroonga_default_tokenizer=TokenMecab </code> \\ ==== TokenMecab ==== 本編で使用している MariaDB with Mroonga (Windows版バイナリ) ではパーサとして形態素解析エンジンの Mecab がバンドルされていて直ぐに利用することができます。Mecab の本体は以下に配置されています: <code> {XAMPP-Folder}/mysql/bin/mecab.exe </code> Mecabの設定ファイル mecabrc の配置場所と内容を以下の示します: ''{XAMPP-Folder}/mysql/etc/mecabrc'' <code ini> ; Configuration file of MeCab dicdir = $(rcpath)\..\share\mecab\dic\naist-jdic </code> mecabrc では形態素解析で使用する辞書が設定されています。初期設定の辞書としては、Mroongaにバンドルされている [[https://ja.osdn.net/projects/naist-jdic/|naist-jdic]] が指定されています。他の辞書に変えるときは、上の ''dicdir'' を変更するだけです。 以下は「[[mroonga:10.7:tutorial|検索チュートリアル]]」で示した例を、Mecabのパーサに替えたものです。 <code sql> CREATE TABLE diaries_mecab ( id INT PRIMARY KEY AUTO_INCREMENT, content VARCHAR(255), FULLTEXT INDEX (content) COMMENT 'tokenizer "TokenMecab"' ) ENGINE = Mroonga COLLATE utf8_unicode_ci; INSERT INTO diaries_mecab (content) VALUES ("今日の天気は晴れでしょう。"); INSERT INTO diaries_mecab (content) VALUES ("今日の天気は雨でしょう。"); INSERT INTO diaries_mecab (content) VALUES ("明日の東京都の天気は晴れでしょう。"); INSERT INTO diaries_mecab (content) VALUES ("明日の京都の天気は雨でしょう。"); </code> 以下の検索を実行します: <code sql> SELECT * FROM diaries_mecab WHERE MATCH(content) AGAINST('明日 京都 天気'); </code> 結果は以下のように出力されます: <code sql> 明日の京都の天気は雨でしょう。 </code> 検索チュートリアルの[[mroonga:10.7:tutorial#自然言語検索|例]]では、トークナイザーがバイグラム (TokenBigram) だったので、「明日の東京都の天気は晴れでしょう。」にもヒットしてしまいましたが、Mecabの場合は形態素解析により「東京都」と「京都」を区別するのでこのような現象は起こりません。 「明日の東京都の天気は晴れでしょう。」がバイグラムとMecabとでどのようにトークン化をされるかを確認するには、以下のようにSELECT文からGroongaコマンドを使います。 バイグラムの場合: <code sql> SELECT mroonga_command('tokenize TokenBigram "明日の東京都の天気は晴れでしょう。"'); </code> <code json> [ {"value":"明日","position":0,"force_prefix":false,"force_prefix_search":false}, {"value":"日の","position":1,"force_prefix":false,"force_prefix_search":false}, {"value":"の東","position":2,"force_prefix":false,"force_prefix_search":false}, {"value":"東京","position":3,"force_prefix":false,"force_prefix_search":false}, {"value":"京都","position":4,"force_prefix":false,"force_prefix_search":false}, {"value":"都の","position":5,"force_prefix":false,"force_prefix_search":false}, {"value":"の天","position":6,"force_prefix":false,"force_prefix_search":false}, {"value":"天気","position":7,"force_prefix":false,"force_prefix_search":false}, {"value":"気は","position":8,"force_prefix":false,"force_prefix_search":false}, {"value":"は晴","position":9,"force_prefix":false,"force_prefix_search":false}, {"value":"晴れ","position":10,"force_prefix":false,"force_prefix_search":false}, {"value":"れで","position":11,"force_prefix":false,"force_prefix_search":false}, {"value":"でし","position":12,"force_prefix":false,"force_prefix_search":false}, {"value":"しょ","position":13,"force_prefix":false,"force_prefix_search":false}, {"value":"ょう","position":14,"force_prefix":false,"force_prefix_search":false}, {"value":"う。","position":15,"force_prefix":false,"force_prefix_search":false}, {"value":"。","position":16,"force_prefix":false,"force_prefix_search":false} ] </code> Mecabの場合: <code sql> SELECT mroonga_command('tokenize TokenMecab "明日の東京都の天気は晴れでしょう。"'); </code> <code json> [ {"value":"明日","position":0,"force_prefix":false,"force_prefix_search":false}, {"value":"の","position":1,"force_prefix":false,"force_prefix_search":false}, {"value":"東京","position":2,"force_prefix":false,"force_prefix_search":false}, {"value":"都","position":3,"force_prefix":false,"force_prefix_search":false}, {"value":"の","position":4,"force_prefix":false,"force_prefix_search":false}, {"value":"天気","position":5,"force_prefix":false,"force_prefix_search":false}, {"value":"は","position":6,"force_prefix":false,"force_prefix_search":false}, {"value":"晴れ","position":7,"force_prefix":false,"force_prefix_search":false}, {"value":"でしょ","position":8,"force_prefix":false,"force_prefix_search":false}, {"value":"う","position":9,"force_prefix":false,"force_prefix_search":false}, {"value":"。","position":10,"force_prefix":false,"force_prefix_search":false}] ] </code> \\ ===== トークンフィルター ===== Mroongaではトークン化の後に、トークンに所定の処理を行うトークンフィルターを指定することができます。トークンフィルターを CREATE TABLE 文の中で指定するには、''COMMENT'' を使用した以下の構文を使用します: <code sql> FULLTEXT [INDEX] [インデックス名] (カラム1,...) COMMENT 'token_filters "フィルター名"' </code> 以下の3つの組込みフィルターを使用できます。詳しくはGroongaの[[https://groonga.org/ja/docs/reference/token_filters.html|ドキュメント]]を参照して下さい。 * [[https://groonga.org/ja/docs/reference/token_filters/token_filter_nfkc100.html|TokenFilterNFKC100]] \\ NormalizerNFKC100 と同じ正規化をトークン化後に使用できます。\\ * [[https://groonga.org/ja/docs/reference/token_filters/token_filter_stem.html|TokenFilterStem]] \\ トークンをステミングします(語形の変化を取り除き、同一の単語表現に変換する処理)。\\ * [[https://groonga.org/ja/docs/reference/token_filters/token_filter_stop_word.html|TokenFilterStopWord]] \\ トークンからストップワードを除去します。 \\
mroonga/10.7/config.txt
· 最終更新: 2020/11/11 10:00 by
y2sunlight
ページ用ツール
文書の表示
以前のリビジョン
バックリンク
文書の先頭へ