Sudachiプラグイン
このサイトで最も力を入れている設定が「検索」です。初稿である「検索に悩む」から既に8年弱が経過し、当時の知識では理解出来なかったことも、今ではある程度わかるようにはなりました。とは言え「検索=索引」はまだまだ奥が深く、これからも探索が必要なことは変わりません。
現在の設定では索引のど真ん中は「Elasticsearch」を採用し、WordPressのプラグインとしては「ElasticPress」を使用しています。日本語環境への適応という点では「Elasticsearch」のプラグインに「analysis-sudachi」を追加しています。「Sudachi」は日本発の日本語形態素解析器で「Elasticsearch」対応プラグインが「analysis-sudachi」です。
WordPress用プラグインである「ElasticPress」は日本語には全く対応していないので、設定を大きく変更する必要があります。その設定も「analysis-sudachi」プラグインのバージョンに大きく依存しています。今回はその辺りを説明したいと思います。
最近までの安定バージョンは「analysis-sudachi-2.1.1」でした。久しぶりにメジャーバージョンアップが行われ「analysis-sudachi-3.0.0」がリリースされました。早速ソースをダウンロードしてビルドからプラグインのバージョンアップを行ったところ、従来の「ElasticPress」の設定では期待した検索結果が出なくなりました。
これまでは「ElasticPress」が使用するトークナイザーを「sudachi_tokenizer」に変更する設定を追加し、それでも期待値を得られない対象については「類義語」として「Elasticsearch」に追加する設定としていました。「analysis-sudachi-2.1.1」まではこの組み合わせでも「類義語」からも検索結果を拾ってくれていましたが、「analysis-sudachi-3.0.0」からは「Elasticsearch」に追加した「類義語」はスルーされるようになりました。実際のところ類義語と言っても大きな辞書を使いたかった訳ではなく、ある特定の記事のタイトルを「・(中点)」無しで検索しても対象に含めたかっただけです。具体的には以前の記事に「ローグ・ワン」と言う映画の紹介・感想記事があり、その記事を「ローグワン」と言う中点無しで検索しても対象に含めたかったのですが、検索対象を細かく分割すると「ログ」とか「ワン」だけで検索してしまい、検索結果が汚くなってしまうので「類義語」辞書で回避しようという魂胆でした。
前述のように「analysis-sudachi-3.0.0」以降は「Elasticsearch」の類義語をスルーしてしまうようなので、「Sudachi」の方にユーザー辞書を追加して対応することにしました。ユーザー辞書の作成はいろいろググった結果「sudachipy」の「ubuild」を使って出来ることがわかりました。まずは「sudachipy」のインストールですが、「apple silicon」のバイナリはまだ提供されていないようなので、開発機のMacbook Pro(M1)のVM上のUbuntuではビルド&インストールが必要です。本番環境はx86アーキテクチャなのでバイナリを「pip3」を使ってインストール出来ます。「sudachipy」がインストール出来たら、以下のようなコマンドでユーザー辞書を作成することが出来ます。「sudachi」用の辞書は事前にダウンロードが必要です。
sudachipy ubuild -d full -o user_dict.dic -s ~/sudachi/dict/20230110/system_full.dic user_dict.txt
元になるCSVファイルは以下のようなフォーマットです。詳細は公式サイトでご確認下さい。今回は前述の通り「ローグワン」で検索しても「ローグ・ワン」が対象に含まれる点のみを対応する内容です。
ローグ・ワン,4786,4786,-32768,ローグ・ワン,名詞,固有名詞,一般,*,*,*,ローグワン,ローグ・ワン,*,*,*,*,* rogue one,4786,4786,-32768,rogue one,名詞,固有名詞,一般,*,*,*,ローグワン,ローグ・ワン,*,*,*,*,* rogueone,4786,4786,-32768,rogueone,名詞,固有名詞,一般,*,*,*,ローグワン,ローグ・ワン,*,*,*,*,*
以下は変更した「ElasticPress」のマッピングファイル設定の一部です。
'analysis' => array( 'tokenizer' => array( 'sudachi_tokenizer' => array( 'type' => 'sudachi_tokenizer', 'split_mode' => 'A', 'additional_settings' => '{"systemDict":"system_full.dic","userDict":["user_dict.dic"]}' ), ), 'analyzer' => array(
今回から「additional_settings」でダイレクトにシステム辞書とユーザー辞書を指定する方法にしました。この変更により、検索ワードが「ローグワン」でも「ローグ・ワン」であっても検索結果は「ローグ・ワン」だけが表示されるという、とても高品質な検索環境を構築することが出来ました。ちなみに、上のCSVファイルにあるように「rogue one」や「rogueone」で検索しても「ローグ・ワン」だけが表示されます。