🍵

Solr9:デフォルトのKuromojiとUniDicを組み込んだKuromojiを共存させる

2023/03/30に公開

概要

Solr9のkuromojiでUniDic2.1.2を使うにて、デフォルトのIPADicの代わりにUniDicを組み込んだKuromojiのビルド方法を提示していただきました。Solr8以前から公式で提供されているIPADicを組み込んだKuromojiとNEologdを組み込んだKuromojiを併用していたので、Solr9でもIPADicを組み込んだKuromojiとUniDicを組み込んだKuromojiを併存させていきたいと思います。

方法してはKuromojiのパッケージ名を改変してビルドを行いました。すなわち、org.apacheを任意のドメイン名に変更したKuromojiをビルドしてSolrに設置します。

環境

  • Alima Linux 9.1

  • openjdk 11

  • Solr 9.1.1

  • Lucene 9.3.0

パッケージ名の変更方法

Luceneをダウンロードした後に、lucene/analysis/kuromoji/src/java にてKuromojiのソースファイルを確認すると、パッケージ名が下記のようにorg.apache.lucene.analysis.jaであることがわかります。

これを[任意のドメイン名].lucene.analysis.jaに変えた上でビルドを行い、併存を図ろうという魂胆です。

Kuromojiのパッケージ名を変更するシェルスクリプトmod_package.shを作成しました。lucene直下のディレクトリにgistからダウンロードします

curl -O https://gist.githubusercontent.com/KANATAKA/a138080f4e4a5b983d859ca91e91f73a/raw/1fc6fbcfc5fd490c522ef6d95ffe52ad86696654/mod_package.sh

luceneの直下で任意のドメイン名を引数で指定してmod_package.shを実行します。この例では慣例に従ってcom.exampleを使用しました。

sh mod_package.sh com.example

以上です

mod_package.shで行っていること

  • lucene/analysis/kuromoji/src/java 以下のディレクトリ構成を任意のドメイン名を使用したものに変更します
  • lucene/analysis/kuromoji/src/java 以下のjavaファイルにおけるorg.apache.lucene.analysis.jaのパッケージ宣言を任意のドメイン名を使ったものに置換します(置換前のファイルは拡張子.bakをつけて別途保存します)
  • gradle/generation/kuromoji.gradle のパッケージ名を任意のドメイン名を使用したものに変更します

おそらくこういった処理はビルドツールかIDEで行えるのでしょうが、JavaにもGradleにも明るくないので泥臭くシェルスクリプトで行いました。結果としてSolr8時代にNEologdを組み込んだKuromojiをビルドする際に使っていたシェルスクリプトをちょっと変更するだけでGradleを使ったビルドにも対応できました。

ビルド手順への組み込み

上記は説明のためにただKuromojiのパッケージ名を変えただけですが、実際はパッケージ名の変更と辞書ファイルを変更したKuromojiのビルドをセットで行うと思います。

別記事辞書ファイルを編集したUniDicをSolr9に組み込むの手順においては、パッチを当てた後、辞書のビルドを行う前にパッケージ名の変更を実行します。

すなわち、手順の概要は以下の通りとなります。

  • Luceneのダウンロード

  • 4つのパッチをダウンロードし、Luceneへ適用する

  • mod_package.shをダウンロードして実行。パッケージ名を変更する

  • 辞書をビルドする→パッケージ名の変更が反映されたjarができる

  • Solrへ設置する

デフォルトのKuromojiと併存を図るのが目的なので、Solrへ設置する際はオリジナルのlucene-analysis-kuromoji-9.3.0.jarはそのまま使います。

パッケージ名を変えたKuromojiをSolrで使用する

Solrのtext_jaというフィールドタイプは、tokenizer に name="japanese"が指定されていますが、これはorg.apache.lucene.analysis.ja.JapaneseTokenizerFactoryが使われます。

今回、パッケージ名を変えたKuromojiを使うために、text_ja_unidicという新たなフィールドタイプを定義してみたいと思います。例えばこんな感じです。

 <fieldType name="text_ja_unidic" class="solr.TextField" autoGeneratePhraseQueries="false" positionIncrementGap="100">
    <analyzer>
      <tokenizer class="com.example.lucene.analysis.ja.JapaneseTokenizerFactory" mode="normal"/>
      <filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="false"/>
      <filter class="com.example.lucene.analysis.ja.JapaneseBaseFormFilterFactory"/>
      <filter class="com.example.lucene.analysis.ja.JapanesePartOfSpeechStopFilterFactory" tags="lang/stoptags_ja.txt"/>
      <filter class="solr.CJKWidthFilterFactory"/>
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_ja.txt"/>
      <filter class="solr.JapaneseKatakanaStemFilterFactory" minimumLength="5"/>
      <filter class="solr.LowerCaseFilterFactory"/>
      <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
    </analyzer>
  </fieldType>

tokenizerとしてcom.example.lucene.analysis.ja.JapaneseTokenizerFactoryを指定しています。同時にjapaneseBaseFormフィルターとjapanesePartOfSpeechStopフィルターにもカスタムパッケージ名を指定するのがポイントです。

これで、text_jaフィールドタイプを使った場合はデフォルトのIPADicが組み込まれたKuromojiを、text_ja_unidicフィールドタイプを使った場合はUniDicが組み込まれたKuromojiを使えるようになりました。

トークナイズ結果の比較

text_jaフィールドタイプとtext_ja_unidicフィールドタイプで「自動車にのって泥鰌寿司を食べた」をトークナイズした結果を比較してみます。2つの違う辞書を内蔵したKuromojiが併存できていることを確認できると思います。

text_jaフィールドタイプの場合

自動車 / のる / 泥鰌 / 寿司 / 食べる とトークナイズされました

text_ja_unidicフィールドタイプの場合

自動 / 車 / のる / 泥鰌寿司 / 食べる とトークナイズされました

参考文献

Discussion