🌞

辞書ファイルを編集したUniDicをSolr9に組み込む

2023/03/30に公開

概要

Solr8までは辞書ファイルを編集したNEologdを使っていました。Solr9に対応しようとした場合、ビルドツールがAntからGradleに変わっているので既存の方法が使えず二の足を踏んでいたところ、UniDicを組み込んだKuromojiをビルドする手順を示したこちらの記事を見つけました。藤那花多さん、ありがとうございます!

辞書ファイルを編集する必要性

NEologdでは例えば辞書に「島の海」があるために、「宮古島の海」が 宮古 / 島の海 にトークナイズされて「宮古島」でヒットしないといった不都合があり、これを解消するために辞書ファイルを編集した上でビルドする運用を行っていました。UniDic2.1.2の辞書には「島の海」は存在しないようですが、内蔵辞書ファイルが手元で編集できる可能性を担保しておきたいので、藤那花多さんが作成されたkuromoji.gradleのパッチをforkして再ビルド用のタスクを追加したパッチを作成しました。

なにぶんJavaにもGradleにも明るくないので、私のパッチを使わずともオプションの与え方とかで?再ビルドできるのではないかという疑念はありますが、内蔵辞書ファイルを編集する手順を記録する意味でもここに記します。

環境

  • Alima Linux 9.1

  • openjdk 11

  • Solr 9.1.1

  • Lucene 9.3.0

ビルド手順

ほぼSolr9のkuromojiでUniDic2.1.2を使うと内容的に重複しますが、記事を行ったり来たりする不便を避けるためにjdkのインストールから記します。

Java11のインストール

Alima Linuxは存在しないパッケージだと認識すると下記のようにインストールを促してきました。すご。

$ java -version
bash: java: command not found...
Install package 'java-11-openjdk-headless' to provide command 'java'? [N/y] 

しかし、よく見るとこれに従ってインストールされるのはheadlessバージョンなのでビルドを行えません。yumで明示的にjava-11-openjdk-develをインストールしました

$ sudo yum install java-11-openjdk-devel

Luceneのダウンロード

元記事と全く同じです。Lucene9.3.0をシャロークローンします

git clone https://github.com/apache/lucene.git --branch releases/lucene/9.3.0 --depth 1

Luceneへのパッチの適用

藤那花多さん作成の3つのパッチファイルをダウンロードしておきます

curl -O https://gist.githubusercontent.com/fjnkt98/b97a30b23d90a257aaba23efe54861bd/raw/c52efb8b364b40a7336616c69fda5c4076504b5d/DictionaryBuilder.java.patch
curl -O https://gist.githubusercontent.com/fjnkt98/9d298769314bc0875a7809fa08bcf250/raw/d2c9a9ecfecc0b948973c8762458ccf3487ae626/TokenInfoDictionaryBuilder.java.patch
curl -O https://gist.githubusercontent.com/fjnkt98/3e7655081b8141116bd39fd5a4b95e6a/raw/fbfad21fb165d1457affd8f411d06109da1ec95c/UnknownDictionaryBuilder.java.patch

2024/06/06追記
Solr9.6.1の場合、UnknownDictionaryBuilder.java.patchのパッチ適用でエラーになったので、こちらを使用してください。

curl -O https://gist.githubusercontent.com/KANATAKA/3cc340359a14a79d0b6810b7afd69697/raw/12f0e582ef04cd93f8d7cabf821723ee6851e080/UnknownDictionaryBuilder.java.patch

kuromoji.gradleにリビルド用のタスクを追加したパッチをダウンロードします

curl -O https://gist.githubusercontent.com/KANATAKA/7cf1c8f4d39f135034fcb38496b83690/raw/c7fd7af1276de7eda0c5f86323d1f0c314651fe6/kuromoji.gradle.patch

パッチをすべて適用します

cd lucene
git apply ../TokenInfoDictionaryBuilder.java.patch
git apply ../DictionaryBuilder.java.patch
git apply ../kuromoji.gradle.patch
git apply ../UnknownDictionaryBuilder.java.patch

辞書のビルド

最初にcompileUnidicタスクを実行します

./gradlew assemble compileUnidic

すると、ビルド成果物が保存される lucene/analysis/kuromoji/build/generate に unidic-mecab-2.1.2_src.zip がダウンロードされ、 unidic-mecab-2.1.2_src ディレクトリに解凍されてるのが確認できます。

辞書の編集

compileUnidicタスクを実行して得られた lucene/analysis/kuromoji/build/generate/unidic-mecab-2.1.2_src/lex.csv がUniDicの辞書ファイルです(たぶん)。
ためしにlex.csvを編集して「自動」と「泥鰌寿司」の行を削除してみます。

再ビルド

lex.csvを編集後、追加しておいたrecompileUnidicタスクで辞書を再ビルドします

./gradlew assemble recompileUnidic

全体をビルドします

./gradlew assemble

これで編集済みの辞書を

lucene/analysis/kuromoji/build/libs/lucene-analysis-kuromoji-9.3.0-SNAPSHOT.jar

に得ることができました。

辞書をビルドした後に再び辞書を編集したい場合

以下の手順を繰り返します

  1. lucene/analysis/kuromoji/build/generate/unidic-mecab-2.1.2_src/lex.csv を編集する
  2. ./gradlew assemble recompileUnidic を実行する
  3. ./gradlew assemble を実行する
  4. 得られたlucene-analysis-kuromoji-9.3.0-SNAPSHOT.jarをSolrに設置する

Solrへの設置

Solrの server/solr-webapp/webapp/WEB-INF/lib にて、

  1. オリジナルのlucene-analysis-kuromoji-9.3.0.jarを削除するか移動させるかリネームします
  2. 成果物のlucene-analysis-kuromoji-9.3.0-SNAPSHOT.jarを好きな名前で設置します
  3. Solrのコアもしくはコレクションをリロードします。

トークナイズ結果の確認

「自動車にのって泥鰌寿司を食べた」をトークナイズさせてみると「自 / 動 / 車 / のる / 泥鰌 / 寿司 / 食べる」となり、「自動」と「泥鰌寿司」をlex.csvから削除した結果が反映されているのがわかります。

Discussion