Wagtail CMSで日本語の全文検索に対応する方法をまとめます。
実行環境
Elasticsearchのインストール
$ curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add - $ echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list $ sudo apt update $ sudo apt install -y elasticsearch $ echo "network.host: localhost" | sudo tee -a /etc/elasticsearch/elasticsearch.yml $ sudo systemctl start elasticsearch $ sudo systemctl enable elasticsearch
Elasticsearchがポート9200で動作していることを確認します。
バージョンは7.17.1でした。
$ curl -X GET 'http://localhost:9200' { "name" : "...", "cluster_name" : "elasticsearch", "cluster_uuid" : "...", "version" : { "number" : "7.17.1", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "...", "build_date" : "...", "build_snapshot" : false, "lucene_version" : "8.11.1", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.0.0-beta1" }, "tagline" : "You Know, for Search" }
ICUとkuromojiのインストール
日本語文字列を正規化するICUと日本語の形態素解析器であるkuromojiを追加します。
$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-icu $ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji $ sudo systemctl restart elasticsearch
Wagtailのバックエンド設定
Backends — Wagtail Documentation 2.16.1 documentation
Elasticsearch7用のPythonクライアントをインストールします。
$ pip install "elasticsearch>=7.0.0,<8.0.0"
settings.WAGTAILSEARCH_BACKENDS
で wagtail.search.backends.elasticsearch7
を使用し、 INDEX_SETTINGS
で日本語を扱うAnalyzerを構成します。
char_filter
にはICU Normalization Character Filterを、 filter
には必要なkuromojiのToken filterを指定します。
WAGTAILSEARCH_BACKENDS = { 'default': { 'BACKEND': 'wagtail.search.backends.elasticsearch7', 'URLS': ['http://localhost:9200'], 'INDEX': 'wagtail', 'TIMEOUT': 5, 'OPTIONS': {}, 'INDEX_SETTINGS': { 'settings': { 'analysis': { 'analyzer': { 'ja_analyzer': { 'type': 'custom', 'char_filter': ['icu_normalizer'], 'tokenizer': 'kuromoji_tokenizer', 'filter': [ 'kuromoji_baseform', 'kuromoji_part_of_speech', 'ja_stop', 'kuromoji_number', 'kuromoji_stemmer' ] } } } } } } }
最後にupdate-indexコマンドでインデクスをリビルドします。
$ ./manage.py update_index
動作確認
部分一致検索が有効なPage.titleで日本語文字列の検索ができることを確認します。
>>> from my_app.models import MyPage >>> from wagtail.search.backends import get_search_backend >>> s = get_search_backend() >>> MyPage.objects.get(title='関西国際空港') <MyPage: 関西国際空港> >>> s.search('関西', MyPage) <SearchResults [<MyPage: 関西国際空港>]> >>> s.search('国際', MyPage) <SearchResults [<MyPage: 関西国際空港>]> >>> s.search('空', MyPage) <SearchResults [<MyPage: 関西国際空港>]> >>> s.search('ほげ', MyPage) <SearchResults []>