🌄

Solr9のkuromojiでUniDic2.1.2を使う

2023/02/01に公開

概要

Solr9.1のkuromojiでUniDic2.1.2を使えるようにします。

UniDicは国立国語研究所によって開発された、形態素解析器MeCab用の解析用辞書です。
形態素解析用辞書にはIPA(IPADic)やNAIST辞書、NEologd辞書などがありますが、IPA辞書は2007年で、NAIST辞書は2011年で、NEologd辞書は2020年で更新が停止しています。UniDicは2022年9月にバージョン3.1.1がリリースされており、2022年現在でも更新が続いている数少ない辞書です。

kuromojiは最新のUniDic3.1.1にはまだ正式対応していないようでしたので、ここではUniDic2.1.2を使用することにします。
(UniDic3.1.1も無理やりビルドすることはできますが、正式対応していないのと辞書サイズが約422MBと大きいので実用的ではないと思われます)

内容的にはこちらのエントリそのままですが、Lucene9からビルドシステムがApache AntからGradleに変更になったことで先人の知恵がそのまま適用できなかったりしたので、覚書ということでこの記事を書きました。

環境

  • Ubuntu 22.04
  • openjdk 11
  • Solr 9.1.0
  • Lucene 9.3.0

手順

Java11のインストール

Java11をインストールします。Ubuntuの場合、aptでインストールすることができます。

sudo apt install openjdk-11-jdk

Luceneのダウンロード

LuceneのGitHubリポジトリから9.3.0をクローンします。
リポジトリのサイズが非常に大きいので、シャロークローンすることをおすすめします。

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

コードの変更

Luceneのいくつかのコードを変更します。変更箇所はこちらのエントリとほとんど同じです。

パッチファイルをGitHub Gistに用意したので、これを各ファイルに適用します。

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
curl -O https://gist.githubusercontent.com/fjnkt98/c6e9cbf47ef062f0ae1ca21380ecbe24/raw/05b1e593d8bf763858448f82829848855033e9a6/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を実行しないとipadicの辞書ができてしまうのでcompileUnidicタスクを単体で実行してから全体ビルドします(Gradleの仕様がよくわかってない)

./gradlew assemble compileUnidic
./gradlew assemble

ビルドが完了すると、lucene/analysis/kuromoji/build/libs以下に辞書のアーカイブファイルが生成されます。何も設定を変更していなければ、lucene-analysis-kuromoji-9.3.0-SNAPSHOT.jarという名前でファイルが作成されます。
ファイルサイズが17MBになっていればOKです。

Dockerfile

辞書のビルドを行うDockerfileを以下に示します。Dockerの実行環境があれば、辞書ファイルを持つDockerイメージが作成できます。

FROM openjdk:11.0.16-slim-buster

RUN apt-get update \
    && apt-get install -y git curl \
    && rm -rf /var/lib/apt/lists/*

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

RUN 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 \
    && curl -O https://gist.githubusercontent.com/fjnkt98/c6e9cbf47ef062f0ae1ca21380ecbe24/raw/05b1e593d8bf763858448f82829848855033e9a6/kuromoji.gradle.patch

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

RUN cd /lucene \
    && ./gradlew clean
# compileUnidic単体でビルド 何かこれやらないとipadicの辞書が出来上がるのでこの手順を挟む
RUN cd /lucene \
    && ./gradlew assemble compileUnidic
RUN cd /lucene \
    && ./gradlew assemble

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

コンテナを起動して、docker cpでホストにコピーすれば辞書が手に入ります。

docker run --rm -it lucene9.3.0-unidic2.1.2:latest bash

Solrで使用する

作成した辞書をSolrに配置して、動作確認をしてみます。

作成した辞書をSolrに適用するには、まずデフォルトでインストールされているkuromoji辞書を無効化します。デフォルトではlucene-analysis-kuromoji-9.3.0.jarという辞書があるので、これを削除するか、lucene-analysis-kuromoji-9.3.0.jar.orgのようにリネームするかします。拡張子が.jarでなくなればなんでもよいです。

そして、生成した辞書オブジェクトをこのディレクトリに配置します。
/opt/solr/server/solr-webapp/webapp/WEB-INF/lib以下に、生成した辞書アーカイブを配置します。

DockerでSolrを実行する場合、以下のようなDockerfileを作成すると簡単に辞書入りSolrが作成できます。

FROM solr:9.1.0

COPY --chown=solr:solr ./lucene-analysis-kuromoji-9.3.0-unidic-2.1.2.jar /opt/solr/server/solr-webapp/webapp/WEB-INF/lib/lucene-analysis-kuromoji-9.3.0.jar

USER solr

上記のDockerfileと同じディレクトリにlucene-analysis-kuromoji-9.3.0-unidic-2.1.2.jarを配置し、Solrイメージをビルドします。

イメージタグは好きなものを付けてください。

docker build -t solr-unidic .

作成したSolrイメージを起動します。

docker run -p 8983:8983 --rm solr-unidic:latest solr-precreate example

起動後にコアが作成されるので、テキスト解析をリクエストしてみましょう。

$ curl -sS 'http://localhost:8983/solr/example/analysis/field?analysis.fieldtype=text_ja' --get --data-urlencode 'analysis.fieldvalue=自動車と自転車の違いはなんでしょう?'  | jq '.analysis.field_types.text_ja.index[13][].text'
"自動"
"車"
"自転"
"車"
"違い"
"なん"

「自動車」が「自動」「車」に分割されれば成功です。

参考文献

GitHubで編集を提案

Discussion