サジェスター
SolrのSuggestComponentは、クエリ用語の自動サジェスチョンをユーザーに提供します。
これを使用して、検索アプリケーションに強力な自動サジェスト機能を実装できます。
スペルチェック機能を使用して自動サジェスト動作を実現することもできますが、Solrにはこの機能専用に設計されたSuggestComponentがあります。
このアプローチは、Luceneのサジェスター実装を利用し、Luceneで利用可能なすべてのルックアップ実装をサポートします。
このサジェスターの主な機能は次のとおりです。
-
ルックアップ実装のプラガビリティ
-
用語辞書のプラガビリティ。辞書実装を柔軟に選択できます。
-
分散サポート
Solrの「techproducts」サンプルにある `solrconfig.xml` には、すでにサジェスター実装が設定されています。検索コンポーネントの詳細については、リクエストハンドラと検索コンポーネントのセクションを参照してください。
「techproducts」サンプルの `solrconfig.xml` には、 `suggest` 検索コンポーネントと `/suggest` リクエストハンドラがすでに設定されています。それを設定の基礎として使用するか、以下で詳述するように、最初から作成できます。
サジェスト検索コンポーネントの追加
最初の手順は、 `solrconfig.xml` に検索コンポーネントを追加し、SuggestComponentを使用するように指示することです。使用できるサンプルコードを次に示します。
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">cat</str>
<str name="weightField">price</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
</lst>
</searchComponent>
サジェスター検索コンポーネントのパラメータ
サジェスター検索コンポーネントは、いくつかの設定パラメータを取ります。
ルックアップ実装( `lookupImpl` 、サジェスチョン辞書での用語の検索方法)と辞書実装( `dictionaryImpl` 、サジェスチョン辞書での用語の格納方法)の選択によって、必要なパラメータの一部が決まります。
以下は、使用されるルックアップまたは辞書の実装に関係なく使用できる主要なパラメータです。以下のセクションでは、実装ごとに追加パラメータが提供されます。
searchComponent名-
必須
デフォルト:なし
検索コンポーネント定義全体に arbitrary な名前を付けます。
searchComponentクラス-
必須
デフォルト:なし
サジェスタークラス。これは `solr.SuggestComponent` として定義する必要があります。
名前-
必須
デフォルト:なし
このサジェスターの記号名。URLパラメータとSearchHandler設定でこの名前を参照できます。1つの `solrconfig.xml` ファイルに複数存在させることができます。上記の構成例では、これは `<str name="name">mySuggester</str>` の行で参照される名前です。
lookupImpl-
オプション
デフォルト: `JaspellLookupFactory`
ルックアップ実装。ルックアップ実装セクションで説明されているように、いくつかの実装が可能です。
dictionaryImpl-
オプション
デフォルト: *説明を参照*
使用する辞書の実装。セクション辞書の実装で説明されているように、いくつかの実装が可能です。
設定されていない場合、デフォルトの辞書実装は
HighFrequencyDictionaryFactoryです。ただし、sourceLocationが使用されている場合、辞書実装はFileDictionaryFactoryになります。 field-
オプション
デフォルト:なし
サジェスト用語の基礎として使用するインデックスからのフィールド。
sourceLocationが空の場合(FileDictionaryFactory以外の辞書実装を意味します)、インデックス内のこのフィールドの用語が使用されます。サジェストの基礎として使用するには、フィールドを格納する必要があります。ドキュメント内の他のフィールドの用語で構成される特別な「サジェスト」フィールドを作成するために、copyFieldルールを使用することをお勧めします。
通常、フィールドの分析は最小限(ステミングなし、同義語なしなど)にする必要があります。そのため、スキーマに基本的なトークナイザーまたはフィルターのみを使用するフィールドタイプを作成するという選択肢があります。このようなフィールドタイプの例を次に示します。
<fieldType class="solr.TextField" name="textSuggest" positionIncrementGap="100"> <analyzer> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType>ただし、用語に対してより多くの分析を実行する場合、この最小限の分析は必須ではありません。
ただし、
lookupImplとしてAnalyzingLookupFactoryを使用する場合は、インデックス時およびクエリ時の分析に使用するフィールドタイプルールを定義するオプションがあります。 sourceLocation-
オプション
デフォルト: *説明を参照*
FileDictionaryFactoryを使用する場合の辞書ファイルへのパス。この値が空の場合、メインインデックスが用語と重みのソースとして使用されます。 storeDir-
オプション
デフォルト:なし
辞書ファイルを格納する場所。
buildOnCommitおよびbuildOnOptimize-
オプション
デフォルト:
falsetrueの場合、ルックアップデータ構造はソフトコミット後に再構築されます。falseの場合、ルックアップデータはURLパラメータsuggest.build=trueによって要求された場合にのみ構築されます。すべてのソフトコミットで辞書を再構築するにはbuildOnCommitを使用し、インデックスが最適化された場合にのみ辞書を構築するにはbuildOnOptimizeを使用します。一部のルックアップ実装では、特に大規模なインデックスの場合、構築に時間がかかる場合があります。このような場合、
buildOnCommitまたはbuildOnOptimizeを、特に高頻度のソフトコミットで使用することはお勧めしません。代わりに、suggest.build=trueを指定したリクエストを手動で発行することにより、低い頻度でサジェスターを構築します。 buildOnStartup-
オプション
デフォルト:
falsetrueの場合、Solrの起動時またはコアのリロード時にルックアップデータ構造が構築されます。このパラメータが指定されていない場合、サジェスターはルックアップデータ構造がディスク上に存在するかどうかを確認し、見つからない場合は構築します。これを
trueにすると、サジェスターデータ構造の構築に時間がかかる場合があるため、Solrのコア読み込み(または再読み込み)に時間がかかる可能性があります。通常、これをfalseに設定し、suggest.build=trueでサジェスターを手動で構築することをお勧めします。
ルックアップ実装
lookupImplパラメータは、サジェストインデックスで用語を検索するために使用されるアルゴリズムを定義します。選択できる実装はいくつかあり、いくつかは追加のパラメータを設定する必要があります。
AnalyzingLookupFactory
入力テキストを最初に分析し、分析されたフォームを重み付きFSTに追加してから、ルックアップ時に同じことを行うルックアップ。
この実装では、次の追加のプロパティを使用します。
suggestAnalyzerFieldType-
必須
デフォルト:なし
クエリ時およびビルド時の用語サジェスト分析に使用するフィールドタイプ。
exactMatchFirst-
オプション
デフォルト:
truetrueの場合、完全一致のサジェストが最初に返されます。FST内のプレフィックスまたは他の文字列の重みが大きい場合でも同様です。 preserveSep-
オプション
デフォルト:
truetrueの場合、トークン間の区切り文字が保持されます。これは、サジェストがトークン化に依存することを意味します(例:baseballはbase ballとは異なります)。 preservePositionIncrements-
オプション
デフォルト:
falsetrueの場合、サジェスターは位置増分を保持します。これは、ギャップを残すトークンフィルター(たとえば、StopFilterがストップワードに一致する場合)の位置がサジェスターの構築時に考慮されることを意味します。
FuzzyLookupFactory
これは、AnalyzingSuggesterの拡張ですが、ファジーな性質を持つサジェスターです。類似度はレーベンシュタイン距離アルゴリズムによって測定されます。
この実装では、次の追加のプロパティを使用します。
exactMatchFirst-
オプション
デフォルト:
truetrueの場合、完全一致のサジェストが最初に返されます。FST内のプレフィックスまたは他の文字列の重みが大きい場合でも同様です。 preserveSep-
オプション
デフォルト:
truetrueの場合、トークン間の区切り文字が保持されます。これは、サジェストがトークン化に依存することを意味します(例:「baseball」は「base ball」とは異なります)。 maxSurfaceFormsPerAnalyzedForm-
オプション
デフォルト:
256単一の分析されたフォームに対して保持するサーフェスフォームの最大数。サーフェスフォームが多すぎる場合は、重みの最も低いものを破棄します。
maxGraphExpansions-
オプション
デフォルト:
-1FST(「インデックス時」)を構築するとき、トークンストリームグラフを通る各パスを個別のエントリとして追加します。これにより、単一のサジェストに追加される拡張の上限が設定されます。
preservePositionIncrements-
オプション
デフォルト:
falsetrueの場合、サジェスターは位置増分を保持します。これは、ギャップを残すトークンフィルター(たとえば、StopFilterがストップワードに一致する場合)の位置がサジェスターの構築時に考慮されることを意味します。 maxEdits-
オプション
デフォルト:
1許可される文字列編集の最大数。Solrのハードリミットは
2です。 transpositions-
オプション
デフォルト:
truetrueの場合、転位はプリミティブ編集操作として扱われる必要があります。 nonFuzzyPrefix-
オプション
デフォルト:
1サジェストと一致する必要がある共通の非ファジープレフィックス一致の長さ。
minFuzzyLength-
オプション
デフォルト:
3文字列編集が許可される前のクエリの最小の長さ。
unicodeAware-
オプション
デフォルト:
falsetrueの場合、maxEdits、minFuzzyLength、transpositions、およびnonFuzzyPrefixパラメータは、バイトではなくUnicodeコードポイント(実際の文字)で測定されます。
AnalyzingInfixLookupFactory
入力テキストを分析し、インデックス付きテキスト内の任意のトークンとのプレフィックス一致に基づいて一致を提案します。これは、辞書にLuceneインデックスを使用します。
この実装では、次の追加のプロパティを使用します。
indexPath-
オプション
デフォルト: *説明を参照*
AnalyzingInfixSuggesterを使用する場合、インデックスが構築される独自のパスを提供できます。デフォルトはanalyzingInfixSuggesterIndexDirで、コレクションのdata/ディレクトリに作成されます。 minPrefixChars-
オプション
デフォルト:
4PrefixQueryが使用される前の先頭文字の最小数。これより短いプレフィックスは、文字nグラムとしてインデックス付けされます(インデックスサイズが増加しますが、ルックアップが高速になります)。
allTermsRequired-
オプション
デフォルト:
truetrueの場合、すべての用語が必要になります。 highlight-
オプション
デフォルト:
trueサジェスト用語を強調表示します。
この実装はコンテキストフィルタリングをサポートしています。
BlendedInfixLookupFactory
AnalyzingInfixSuggesterの拡張機能であり、一致したドキュメント全体でプレフィックス一致の重み付けを行うための追加機能を提供します。ヒットがサジェストの先頭に近いほど、スコアが高くなります。
この実装では、次の追加のプロパティを使用します。
blenderType-
オプション
デフォルト:
position_linear最初の一致する単語の位置を使用して重み係数を計算するために使用されます。利用可能なオプションは次のとおりです。
-
position_linear:先頭との一致には高いスコアが付けられます。weightFieldValue * (1 - 0.10*position) -
position_reciprocal:先頭との一致には高いスコアが付けられます。サジェストの先頭から遠い位置にある一致のスコアは、線形よりも速く減衰します。weightFieldValue / (1 + position) -
position_exponential_reciprocal:先頭との一致には高いスコアが付けられます。サジェストの先頭から遠い位置にある一致のスコアは、逆数よりも速く減衰します。weightFieldValue / pow(1 + position,exponent)このブレンダータイプを使用する場合、追加のパラメータが利用可能です。
-
exponent:スコアの減少速度を制御します。デフォルトは2.0です。
-
-
numFactor-
オプション
デフォルト:
10結果がプルーニングされる検索済み要素の数を乗算する係数。
indexPath-
オプション
デフォルト: *説明を参照*
BlendedInfixSuggesterを使用する場合、インデックスが構築される独自のパスを提供できます。デフォルトのディレクトリ名はblendedInfixSuggesterIndexDirで、コレクションのデータディレクトリに作成されます。 minPrefixChars-
オプション
デフォルト:
4PrefixQueryが使用される前の先頭文字の最小数。これより短いプレフィックスは、文字nグラムとしてインデックス付けされます。これにより、インデックスサイズが増加しますが、ルックアップが高速になります。
この実装はコンテキストフィルタリングをサポートしています。
FreeTextLookupFactory
最も可能性の高い次のトークンを予測するために、最後のトークンと、ユーザーが入力している最後のトークンのプレフィックス(存在する場合)を調べます。考慮する必要がある以前のトークンの数も指定できます。このサジェスターは、プライマリサジェスターがサジェストを見つけられない場合のフォールバックとしてのみ使用されます。
この実装では、次の追加のプロパティを使用します。
suggestFreeTextAnalyzerFieldType-
必須
デフォルト:なし
「クエリ時」および「ビルド時」にサジェストを分析するために使用されるフィールドタイプ。
ngrams-
オプション
デフォルト:
2シングルが辞書になる最大トークン数。これを増やすということは、サジェストを作成するときに、前の2つ以上のトークンを考慮に入れる必要があることを意味します。
FSTLookupFactory
オートマトンベースのルックアップ。この実装は構築に時間がかかりますが、メモリコストは最も低くなります。より洗練された一致結果が必要な場合を除き、この実装を使用することをお勧めします。その場合は、Jaspell実装を使用する必要があります。
この実装では、次の追加のプロパティを使用します。
exactMatchFirst-
オプション
デフォルト:
truetrue(デフォルト)の場合、完全一致のサジェストが最初に返されます。FST内のプレフィックスまたは他の文字列の重みが大きい場合でも同様です。 weightBuckets-
オプション
デフォルト:なし
サジェスターが辞書の構築中に使用する重みの個別のバケットの数。
WFSTLookupFactory
よりきめ細かいランキングのためのFSTLookupの代替となる重み付きオートマトン表現。WFSTLookupはバケットを使用せず、最短パスアルゴリズムを使用します。
重みは整数である必要があります。重みが欠落している場合は、1.0と見なされます。spellcheck.onlyMorePopular=trueが選択されている場合、重みは一致するサジェストのソートに影響します。重みは「人気」スコアとして扱われ、重みの高いサジェストは重みの低いサジェストよりも優先されます。
JaspellLookupFactory
JaSpellプロジェクトの3項トライに基づく、より複雑なルックアップ。より洗練された一致結果が必要な場合は、この実装を使用してください。
辞書の実装
辞書の実装は、用語の保存方法を定義します。いくつかのオプションがあり、必要に応じて1つのリクエストで複数の辞書を使用できます。
DocumentDictionaryFactory
インデックスから取得した用語、重み、およびオプションのペイロードを持つ辞書。
この辞書の実装では、サジェスター全般およびルックアップ実装について説明されているパラメーターに加えて、次のパラメーターを使用します。
weightField-
オプション
デフォルト:なし
格納されているフィールド、または数値型のDocValueフィールド。
payloadField-
オプション
デフォルト:なし
payloadFieldは、格納されているフィールドである必要があります。 contextField-
オプション
デフォルト:なし
コンテキストフィルタリングに使用するフィールド。フィルタリングをサポートするルックアップ実装は一部のみであることに注意してください。
DocumentExpressionDictionaryFactory
この辞書の実装はDocumentDictionaryFactoryと同じですが、ユーザーはweightExpressionタグに任意の式を指定できます。
この辞書の実装では、サジェスター全般およびルックアップ実装について説明されているパラメーターに加えて、次のパラメーターを使用します。
payloadField-
オプション
デフォルト:なし
payloadFieldは、格納されているフィールドである必要があります。 weightExpression-
必須
デフォルト:なし
サジェスチョンのスコアリングに使用する任意の式。使用するフィールドは数値フィールドである必要があります。
contextField-
オプション
デフォルト:なし
コンテキストフィルタリングに使用するフィールド。フィルタリングをサポートするルックアップ実装は一部のみであることに注意してください。
HighFrequencyDictionaryFactory
この辞書の実装では、非常に一般的な用語が他の用語を圧倒する可能性がある場合に、頻度の低い用語を削除するためのしきい値を追加できます。
この辞書の実装では、サジェスター全般およびルックアップ実装について説明されているパラメーターに加えて、1つのパラメーターを使用します。
threshold-
オプション
デフォルト:
00から1までの値で、ルックアップ辞書に追加するために用語がドキュメント全体のうち、どれだけの割合で出現する必要があるかを示す最小値を表します。
FileDictionaryFactory
この辞書の実装では、サジェストエントリを含む外部ファイルを使用できます。重みとペイロードも使用できます。
辞書ファイルを使用する場合、UTF-8エンコーディングのプレーンテキストファイルである必要があります。辞書ファイルでは、単一の用語とフレーズの両方を使用できます。重みまたはペイロードを追加する場合、それらはfieldDelimiterプロパティで定義された区切り文字(デフォルトは\t、タブ文字)を使用して用語から区切る必要があります。ペイロードを使用する場合、ファイルの最初の行には**必ず**ペイロードを指定する必要があります。
この辞書の実装では、サジェスター全般およびルックアップ実装について説明されているパラメーターに加えて、1つのパラメーターを使用します。
fieldDelimiter-
オプション
デフォルト:
\tエントリ、重み、およびペイロードを区切るために使用する区切り文字を指定します。デフォルトはタブ(
\t)です。ファイル例acquire accidentally 2.0 accommodate 3.0
複数の辞書
1つのSuggestComponent定義に複数のdictionaryImpl定義を含めることができます。
これを行うには、この例のように、個別のサジェスターを定義するだけです。
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">cat</str>
<str name="weightField">price</str>
<str name="suggestAnalyzerFieldType">string</str>
</lst>
<lst name="suggester">
<str name="name">altSuggester</str>
<str name="dictionaryImpl">DocumentExpressionDictionaryFactory</str>
<str name="lookupImpl">FuzzyLookupFactory</str>
<str name="field">product_name</str>
<str name="weightExpression">((price * 2) + ln(popularity))</str>
<str name="sortField">weight</str>
<str name="sortField">price</str>
<str name="storeDir">suggest_fuzzy_doc_expr_dict</str>
<str name="suggestAnalyzerFieldType">text_en</str>
</lst>
</searchComponent>
これらのサジェスターをクエリで使用する場合、リクエストに複数のsuggest.dictionaryパラメーターを定義し、検索コンポーネント定義で各サジェスターに付けられた名前を参照します。レスポンスには、各サジェスターのセクションに用語が含まれます。リクエストとレスポンスの例については、以下の使用例セクションを参照してください。
サジェストリクエストハンドラの追加
検索コンポーネントを追加した後、リクエストハンドラをsolrconfig.xmlに追加する必要があります。このリクエストハンドラは、他のリクエストハンドラと同じように機能し、サジェストリクエストを提供するためのデフォルトパラメータを設定できます。リクエストハンドラ定義には、以前に定義した「サジェスト」検索コンポーネントを含める必要があります。
<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
<lst name="defaults">
<str name="suggest">true</str>
<str name="suggest.count">10</str>
</lst>
<arr name="components">
<str>suggest</str>
</arr>
</requestHandler>
サジェストリクエストハンドラパラメータ
次のパラメータを使用すると、サジェストリクエストハンドラのデフォルトを設定できます。
suggest-
オプション
デフォルト:
falseこのハンドラに送信されたクエリに対して常にサジェスターを実行するため、このパラメータは常に
trueである必要があります。 suggest.dictionary-
必須
デフォルト:なし
検索コンポーネントで構成された辞書コンポーネントの名前。リクエストハンドラで設定することも、クエリ時にパラメータとして送信することもできます。
suggest.q-
オプション
デフォルト:なし
サジェストルックアップに使用するクエリ。指定しない場合、
qパラメータが使用されます。 suggest.count-
オプション
デフォルト:
1Solrが返すサジェスチョンの数を指定します。
suggest.cfq-
オプション
デフォルト:なし
サジェスターでサポートされている場合、コンテキストフィールドに基づいてサジェスチョンをフィルタリングするために使用されるコンテキストフィルタークエリ。
コンテキストフィルタリングは現在、
AnalyzingInfixLookupFactoryとBlendedInfixLookupFactoryでのみサポートされており、Document*Dictionaryによってサポートされている場合のみです。他のすべての実装は、フィルタリングが要求されていないかのように、フィルタリングされていない一致を返します。 suggest.build-
オプション
デフォルト:
falsetrueの場合、サジェスターインデックスが構築されます。これは、最初のリクエストにのみ役立つ可能性があります。特に本番システムでは、すべてのリクエストで辞書を構築することは望ましくないでしょう。辞書を最新の状態に保つ場合は、検索コンポーネントのbuildOnCommitまたはbuildOnOptimizeパラメータを使用する必要があります。 suggest.reload-
オプション
デフォルト:
falsetrueの場合、サジェスターインデックスが再読み込みされます。 suggest.buildAll-
オプション
デフォルト:
falsetrueの場合、すべてのサジェスターインデックスが構築されます。 suggest.reloadAll-
オプション
デフォルト:
falsetrueの場合、すべてのサジェスターインデックスが再読み込みされます。
これらのプロパティは、クエリ時にオーバーライドすることも、リクエストハンドラでまったく設定せずに常にクエリ時に送信することもできます。
使用例
重み付きのサジェスチョンを取得する
これは、単一の辞書と単一のSolrコアを使用した基本的なサジェスチョンです。
クエリ例
https://:8983/solr/techproducts/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=elec
この例では、suggest.qパラメータを使用して文字列「elec」をリクエストし、suggest.buildを使用してサジェスチョン辞書を構築するようにリクエストしました(ただし、すべてのクエリでインデックスを構築することは望ましくないでしょう。代わりに、ドキュメントが定期的に変更される場合は、buildOnCommitまたはbuildOnOptimizeを使用する必要があります)。
レスポンス例
{
"responseHeader": {
"status": 0,
"QTime": 35
},
"command": "build",
"suggest": {
"mySuggester": {
"elec": {
"numFound": 3,
"suggestions": [
{
"term": "electronics and computer1",
"weight": 2199,
"payload": ""
},
{
"term": "electronics",
"weight": 649,
"payload": ""
},
{
"term": "electronics and stuff2",
"weight": 279,
"payload": ""
}
]
}
}
}
}
複数の辞書を使用する
複数の辞書を定義している場合は、クエリで使用できます。
クエリ例
https://:8983/solr/techproducts/suggest?suggest=true&suggest.dictionary=mySuggester&suggest.dictionary=altSuggester&suggest.q=elec
この例では、文字列「elec」をsuggest.qパラメータとして送信し、使用する2つのsuggest.dictionary定義を指定しました。
レスポンス例
{
"responseHeader": {
"status": 0,
"QTime": 3
},
"suggest": {
"mySuggester": {
"elec": {
"numFound": 1,
"suggestions": [
{
"term": "electronics and computer1",
"weight": 100,
"payload": ""
}
]
}
},
"altSuggester": {
"elec": {
"numFound": 1,
"suggestions": [
{
"term": "electronics and computer1",
"weight": 10,
"payload": ""
}
]
}
}
}
}
コンテキストフィルタリング
コンテキストフィルタリングを使用すると、カテゴリ、部門、その他のトークンなど、別のコンテキストフィールドでサジェスチョンをフィルタリングできます。 AnalyzingInfixLookupFactoryとBlendedInfixLookupFactoryは現在、DocumentDictionaryFactoryでサポートされている場合にこの機能をサポートしています。
サジェスター設定にcontextFieldを追加します。この例では、名前を提案し、カテゴリでフィルタリングできるようにします。
<searchComponent name="suggest" class="solr.SuggestComponent">
<lst name="suggester">
<str name="name">mySuggester</str>
<str name="lookupImpl">AnalyzingInfixLookupFactory</str>
<str name="dictionaryImpl">DocumentDictionaryFactory</str>
<str name="field">name</str>
<str name="weightField">price</str>
<str name="contextField">cat</str>
<str name="suggestAnalyzerFieldType">string</str>
<str name="buildOnStartup">false</str>
</lst>
</searchComponent>
コンテキストフィルタリングサジェストクエリの例
https://:8983/solr/techproducts/suggest?suggest=true&suggest.build=true&suggest.dictionary=mySuggester&suggest.q=c&suggest.cfq=memory
サジェスターは、「cat = memory」のタグが付いた製品のサジェスチョンのみを返します。