アナライザー
アナライザーはフィールドのテキストを調べて、トークンストリームを生成します。
アナライザーは、Solrのスキーマの<fieldType>
要素の子として指定します。
通常の使用では、solr.TextField
またはsolr.SortableTextField
型のフィールドのみがアナライザーを指定します。アナライザーを構成する最も簡単な方法は、class属性が完全修飾Javaクラス名である単一の<analyzer>
要素を使用することです。指定されたクラスは、org.apache.lucene.analysis.Analyzer
から派生する必要があります。例:
<fieldType name="nametext" class="solr.TextField">
<analyzer class="org.apache.lucene.analysis.core.WhitespaceAnalyzer"/>
</fieldType>
この場合、単一のクラスWhitespaceAnalyzer
が、指定されたテキストフィールドのコンテンツを分析し、対応するトークンを発行する役割を担います。プレーンな英語の散文など、単純なケースでは、このような単一のアナライザークラスで十分な場合があります。しかし、フィールドコンテンツのより複雑な分析が必要になることがよくあります。
最も複雑な分析要件でさえ、通常は一連の個別で比較的単純な処理ステップに分解できます。すぐにわかるように、Solrディストリビューションには、遭遇する可能性のあるほとんどのシナリオをカバーするトークナイザーとフィルターが多数付属しています。アナライザーチェーンの設定は非常に簡単です。使用するトークナイザーとフィルターのファクトリークラスを、実行する順序で指定する子要素を持つ単純な<analyzer>
要素(class属性なし)を指定します。
例:
名前を使用
<fieldType name="nametext" class="solr.TextField">
<analyzer>
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="stop"/>
<filter name="englishPorter"/>
</analyzer>
</fieldType>
トークナイザーとフィルターファクトリークラスは、シンボリック名(SPI名)で参照されます。ここで、name="standard"はorg.apache.lucene.analysis.standard.StandardTokenizerFactory
を参照します。
クラス名を使用(レガシー)
<fieldType name="nametext" class="solr.TextField">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.StopFilterFactory"/>
<filter class="solr.EnglishPorterFilterFactory"/>
</analyzer>
</fieldType>
org.apache.lucene.analysis
パッケージのクラスは、ここで短縮形のsolr.
プレフィックスで参照できることに注意してください。
この場合、<analyzer>
要素にはAnalyzerクラスは指定されていません。むしろ、より特殊なクラスのシーケンスが一緒に接続され、集合的にフィールドのアナライザーとして機能します。フィールドのテキストはリストの最初の項目(solr.StandardTokenizerFactory
)に渡され、最後の項目(solr.EnglishPorterFilterFactory
)から出力されるトークンは、"nametext" fieldType
を使用するフィールドのインデックス作成またはクエリに使用される用語です。
フィールド値とインデックス付き用語
アナライザーの出力は、指定されたフィールドでインデックス付けされた用語(およびそれらのフィールドに対してクエリを解析するときに使用される用語)に影響しますが、フィールドの格納値には影響しません。例:アナライザーは、「Brown Cow」を2つのインデックス付き用語「brown」と「cow」に分割する可能性がありますが、格納された値は依然として単一の文字列「Brown Cow」になります。 |
分析フェーズ
分析は2つのコンテキストで実行されます。インデックス作成時、フィールドが作成されると、分析から得られるトークンストリームがインデックスに追加され、フィールドの用語セット(位置、サイズなどを含む)が定義されます。クエリ時、検索されている値が分析され、結果の用語がフィールドのインデックスに格納されているものと照合されます。
多くの場合、両方のフェーズに同じ分析を適用する必要があります。例えば、大文字と小文字を区別しない可能性のある完全一致の文字列をクエリする場合など、これが望ましい場合があります。それ以外の場合、インデックス作成時とクエリ時でわずかに異なる分析ステップを適用したい場合があります。
上記の例のように、フィールドタイプに単純な<analyzer>
定義を提供すると、インデックス作成とクエリの両方に使用されます。各フェーズで異なるアナライザーが必要な場合は、タイプ属性で区別された2つの<analyzer>
定義を含めることができます。例えば
名前を使用
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="keepWord" words="keepwords.txt"/>
<filter name="synonymFilter" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer name="standard"/>
<filter name="lowercase"/>
</analyzer>
</fieldType>
クラス名を使用(レガシー)
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.KeepWordFilterFactory" words="keepwords.txt"/>
<filter class="solr.SynonymFilterFactory" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
この理論的な例では、インデックス作成時にテキストがトークン化され、トークンが小文字に設定され、keepwords.txt
にリストされていないトークンは破棄され、残ったトークンはファイルsyns.txt
の同義語ルールで定義されている代替値にマップされます。これは基本的に、可能な値の制限されたセットからインデックスを作成し、それらを元のテキストに存在しない可能性のある値に正規化します。
クエリ時には、クエリ項を小文字に変換することのみが行われます。インデックス作成時に発生するフィルタリングとマッピングの手順は、クエリ項には適用されません。したがって、この例では、クエリはインデックス作成時に保存された正規化された項のみを使用して、非常に正確である必要があります。
複数項展開の分析
一部のタイプのクエリ(つまり、プレフィックス、ワイルドカード、正規表現など)では、ユーザーが提供する入力は、分析を目的とした自然言語ではありません。同義語やストップワードフィルタリングのようなものは、これらのタイプのクエリでは論理的な方法では機能しません。
Solrが複数項展開をもたらすクエリの分析を実行する必要がある場合、フィルターチェーン内の各ファクトリーに対してnormalize
メソッドが呼び出されます。このコンテキストで意味をなさないフィルターを提供するファクトリーは、入力を変更せずに返します。正規化はCharFilterとTokenFilterの両方に適用されます。
ほとんどのユースケースでは、これが最適な動作を提供しますが、これらのタイプのクエリで実行される分析を完全に制御したい場合は、次の例のように、使用するmultiterm
アナライザーを明示的に定義できます。
<fieldType name="nametext" class="solr.TextField">
<analyzer type="index">
<tokenizer name="standard"/>
<filter name="lowercase"/>
<filter name="keepWord" words="keepwords.txt"/>
<filter name="synonym" synonyms="syns.txt"/>
</analyzer>
<analyzer type="query">
<tokenizer name="standard"/>
<filter name="lowercase"/>
</analyzer>
<!-- No analysis at all when doing queries that involved Multi-Term expansion -->
<analyzer type="multiterm">
<tokenizer name="keyword" />
</analyzer>
</fieldType>