Skip to the content.

mastodonの検索にkuromojiを導入して日本語検索に対応する

目的

mastodonでも日本語検索に対応したい。Dockerで運用している環境である。

作業

1. elasticsearchにkuromojiプラグインを入れる

面倒なのでplusminusio/elasticsearchを使用することにした。GitHubのソースを見ての通り、 analysis-icuanalysis-kuromoji が導入されている。もちろん同様のイメージを自分でビルドするようにしてもよい。

どちらにしても docker-compose.yml を編集し

  es:
    restart: always
    #image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10
    image: plusminusio/elasticsearch:7.9.3

使用するイメージを変更しておく。

2. mastodonのソースコードを編集

kuromojiを使うようにソースを編集する。 app/chewy/statuses_index.rb の該当部分を

class StatusesIndex < Chewy::Index
  settings index: { refresh_interval: '15m' }, analysis: {
    filter: {
      english_stop: {
        type: 'stop',
        stopwords: '_english_',
      },
      english_stemmer: {
        type: 'stemmer',
        language: 'english',
      },
      english_possessive_stemmer: {
        type: 'stemmer',
        language: 'possessive_english',
      },
    },
    tokenizer: {
      kuromoji: {
        type: 'kuromoji_tokenizer',
        #mode: 'search',
      },
    },
    analyzer: {
      content: {
        tokenizer: 'kuromoji',
        type: 'custom',
        char_filter: %w(
          icu_normalizer
          html_strip
          kuromoji_iteration_mark
        ),
        filter: %w(
          english_possessive_stemmer
          lowercase
          asciifolding
          kuromoji_stemmer
          kuromoji_number
          kuromoji_baseform
          icu_normalizer
          cjk_width
          english_stop
          english_stemmer
        ),
      },
    },
  }

こんな感じに書き換える。実のところこれもmstdn-plusminus-io/mastodonの引き写しである。

3. イメージ作成

docker-compose.yml を少し編集し、イメージ名を独自のもの、buildを実行するようにしておく。もちろんweb以外のstreamingsidekiqも同様にイメージ名を変更するが、buildは1つを残してコメントアウトしておいてよい。

  web:
    build: .
    image: boronology/mastodon:v3.3.0
    restart: always

できたらイメージをビルドする。

$ docker-compose build web

4. 動かす

$ docker-compose up -d

ここは普段と変わらず。

5. elasticsearchのインデクスを消す

ここからが本題。どうやらプラグインを入れる前後でインデクスの不整合がおきるらしく、いきなりtootctl search deployするとエラーが出て止まる。

[400] {“error”:{“root_cause”:[{“type”:”illegal_argument_exception”,”reason”:”The provided expression [statuses] matches an alias, specify the corresponding concrete indices instead.”}],”type”:”illegal_argument_exception”,”reason”:”The provided expression [statuses] matches an alias, specify the corresponding concrete indices instead.”},”status”:400} (Elasticsearch::Transport::Transport::Errors::BadRequest)

そこで一度インデクスをすべて削除してしまうことにする。

# Elasticsearchのコンテナに入る
$ docker-compose exec es sh

# 存在するインデクスを表示
$ curl -XGET 'http://localhost:9200/_cat/indices?pretty=true'

# インデクスを削除
curl -X DELETE 'http://localhost:9200/statuses_xxxxxx?pretty=true'

これで既存のインデクスが削除できるので、あらためて再生成を行う。

docker-compose run --rm web bin/tootctl search deploy

このときメモリをケチっているとメモリ不足で止まる。 docker-compose.ymlのesで"ES_JAVA_OPTS=-Xms256m -Xmx256m"くらいは用意しておいたほうがいいと思われる。"ES_JAVA_OPTS=-Xms128m -Xmx128m"ではエラーが起きた。

まとめ

elasticsearchの設定を変えたらインデクスを再生成しましょう。