Solr が認識する形でトークナイザーを作成する方法 | KandaSearch Community Support Forum

Solr が認識する形でトークナイザーを作成する方法

トピック作成者:ks-solruserml-bot (2025/03/23 21:14 投稿)
4
OpenOpen

(The bot translated the original post https://lists.apache.org/thread/wv23kzrhwhq5l8ws25nhofcolkqvl1qc into Japanese and reposted it under Apache License 2.0. The copyright of posted content is held by the original poster.)

こんにちは、

Solr 用にカスタムトークナイザーを作成しようとしています。
私は Java 開発者ではありませんが、Lucene のソースコードにある他のトークナイザーを参考にしながら、以下のリポジトリを作成しました。
https://github.com/yasar11732/lucene-zemberek

Maven を使用して JAR ファイルにパッケージ化し、それを他の依存関係の JAR とともに、インスタンスディレクトリ内の lib ディレクトリに配置しました。

しかし、以下のエラーが発生しています。

"A SPI class of type org.apache.lucene.analysis.TokenizerFactory with name 'zemberekTokenizer' does not exist."

トークナイザーファクトリー内で NAME を定義していることは、次のリンク先で確認できます。
https://github.com/yasar11732/lucene-zemberek/blob/master/src/main/java/com/github/yasar11732/lucene_zemberek/ZemberekTokenizerFactory.java#L14

Solr がこのトークナイザーを認識する前に、他に必要な手順があるでしょうか?

よろしくお願いします。

返信投稿者:ks-solruserml-bot (2025/03/23 21:14 投稿)

あなたが見落としている重要な点は、Java レベルでの「サービスプロバイダ」インターフェースの登録です。これは、あなたのクラスを TokenizerFactory の「サービスインターフェース」の実装として認識させるために必要です。

https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html

この登録は、JAR 内の META-INF/services/ パス以下に特定のファイルを配置することで行われます。Lucene がいくつかの TokenizerFactory をどのように登録しているかの例はこちらで確認できます。

https://github.com/apache/lucene/blob/main/lucene/analysis/common/src/resources/META-INF/services/org.apache.lucene.analysis.TokenizerFactory

もし TokenFilterCharFilter を独自に実装したい場合は、それぞれ対応する「インターフェース」に基づいたファイル名で JAR 内に配置する必要があります。

注意: resources/ パスは、Lucene がそのファイルのソースを Git に保持するための場所であり、JAR 内にそのまま存在するわけではありません。
JAR の中にどのような META-INF/services/ ファイルが含まれているかを確認するには、次のようなコマンドを使用できます。

$ jar tf lucene-analysis-common-9.11.1.jar | grep META-INF/services/org.apache.lucene
META-INF/services/org.apache.lucene.analysis.CharFilterFactory
META-INF/services/org.apache.lucene.analysis.TokenFilterFactory
META-INF/services/org.apache.lucene.analysis.TokenizerFactory

私は Maven の経験があまりありませんが、おそらく src/main/resources/META-INF/services/org.apache.lucene.analysis.TokenizerFactory というファイルをリポジトリ内に作成すれば、Maven の jar プラグインが適切に処理してくれるはずです。

— Hoss
http://www.lucidworks.com/

返信投稿者:ks-solruserml-bot (2025/03/23 21:14 投稿)

ありがとうございます。その問題は解決しました。

しかし、新たな問題に直面しています。

Caused by: java.lang.IllegalArgumentException: resource tokenization/sentence-boundary-model.bin not found.
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:220) ~[?:?]
    at com.google.common.io.Resources.getResource(Resources.java:196) ~[?:?]
    at zemberek.tokenization.TurkishSentenceExtractor.fromDefaultModel(TurkishSentenceExtractor.java:51) ~[?:?]
    at zemberek.tokenization.TurkishSentenceExtractor.access$100(TurkishSentenceExtractor.java:28) ~[?:?]
    at zemberek.tokenization.TurkishSentenceExtractor$Singleton.<init>(TurkishSentenceExtractor.java:261) ~[?:?]
    at zemberek.tokenization.TurkishSentenceExtractor$Singleton.<clinit>(TurkishSentenceExtractor.java:256) ~[?:?]
    at zemberek.tokenization.TurkishSentenceExtractor.<clinit>(TurkishSentenceExtractor.java:33) ~[?:?]
    at com.github.yasar11732.lucene_zemberek.ZemberekTokenizerFactory.<clinit>(ZemberekTokenizerFactory.java:16) ~[?:?]

しかし tokenization/sentence-boundary-model.binzemberek-tokenization-0.17.1.jar の中に含まれており、この JAR も lib ディレクトリにコピーしています。

興味深いことに、同じ zemberek.tokenization.TurkishSentenceExtractor クラスを使用して、単純なコンソールアプリケーションを実行すると問題なく動作します(このクラスは tokenization/sentence-boundary-model.bin をロードしようとします)。
しかし、Solr にロードすると tokenization/sentence-boundary-model.bin を見つけられないようです。

よろしくお願いします。

返信投稿者:ks-solruserml-bot (2025/03/23 21:15 投稿)

ようこそ、Java の ClassLoader 地獄 へ!

まず明確にする必要があります。「lib」ディレクトリとは、具体的にどこを指していますか?

もし以下の場所を指しているのであれば…
https://solr.apache.org/guide/solr/latest/configuration-guide/libs.html

…この方法は 推奨されません。代わりに、カスタムコードを カスタムモジュールディレクトリ に配置することをお勧めします。
https://solr.apache.org/guide/solr/latest/configuration-guide/solr-modules.html

または、Solr の「パッケージマネージャー」を使用する方法もありますが、私はこの方法に関する経験があまりありません。
https://solr.apache.org/guide/solr/latest/configuration-guide/package-manager.html

上記のいずれかの方法を試すことで、solrconfig.xml<lib .../> を使用するよりも問題が解決する可能性があります。


さて、具体的にあなたの問題の原因ですが…

最初に Google で調べた結果から推測するに、あなたが使用しているコードは以下のものではないでしょうか?
https://github.com/ahmetaa/zemberek-nlp/blob/a9c0f88210dd6a4a1b6152de88d117054a105879/tokenization/src/main/java/zemberek/tokenization/TurkishSentenceExtractor.java#L49

このコードでは、com.google.common.io.Resources.getResource(...)引数が 1 つのバージョン を使用しています。このメソッドは コンテキストクラスローダー を使用するため、Solr のクラスローダーとは異なる可能性があります。

もしコードを修正できるのであれば、2 つの引数を持つ getResource(...) を使用し、TurkishSentenceExtractor.class を渡すように変更してください。
そうすれば、Solr が作成した適切なクラスローダーを常に使用できるようになります(Solr が JAR ファイルをどこからロードしているかに関係なく動作するはずです)。

コードを直接変更できない場合の対策

もし TurkishSentenceExtractor クラスを 直接修正できない 場合は、以下の方法を試すことができます。

  1. Factory クラス側で DEFAULT を使わずに、独自の TurkishSentenceExtractor インスタンスを作成する。
    • DEFAULT を使用する代わりに、手動で sentence-boundary-model.bin をロードし、それを TurkishSentenceExtractor に渡すようにする。

ただし、あなたのエラーは TurkishSentenceExtractor のクラスロード時に発生しているように見える ため、この方法でも問題が解決しない可能性があります。

最終手段: JAR を Solr の WEB-INF/lib に配置する

もう一つの回避策として、JAR を Solr の WEB-INF/lib に配置する という方法があります。
この方法を使うと、どのクラスローダーが使用されるかに関係なく、すべてのクラスが見つかる はずです。

この方法はあまり良い解決策とは言えませんが、Solr の Spatial Plugin では以前にこの方法が使われた前例があります。
https://solr.apache.org/guide/solr/latest/query-guide/spatial-search.html#jts-and-polygons-flat

— Hoss
http://www.lucidworks.com/

返信投稿者:ks-solruserml-bot (2025/03/23 21:15 投稿)

結局、簡単な方法を選び、すべての JAR を WEB-INF/lib に配置しました。
今のところ、すべて正常に動作しているようです。

よろしくお願いします。

トピックへ返信するには、ログインが必要です。

KandaSearch

Copyright © 2006-2025 RONDHUIT Co, Ltd. All Rights Reserved.

投稿の削除

この投稿を削除します。よろしいですか?