web-dev-qa-db-ja.com

Search API Solr:ステミングがある場合とない場合のフルテキストフィールドにインデックスを付ける方法

要するに:Drupal Search APIで、フルテキストフィールドの語幹バージョンと非語幹バージョンのインデックスを作成する方法はありますか?フィールドデータをスキーマファイルのcopyfieldにハードコーディングすることに頼らずにSolr?

(そうでない場合、最も安全なのは、Drupal /これを行うためのSearch APIフレンドリーなアプローチですか?たとえば、Drupalフィールドマシン名をSolrスキーマファイルで使用して、多分?)


背景:Apache Solrで作業するときの一般的な方法は、SnowballPorterFilterFactory(stemmers make検索はWordの文法的な「語幹」で一致するため、たとえば、「walking」と一致するコンテンツを「walked」と検索します)、次にフルテキストフィールドをコピーします(例 copyfield )を使用して、2つの複製の一方をステミングし、もう一方をステミングしない。

この一般的なアプローチには2つの利点があります(処理が増えるという犠牲を伴います)。

  • 完全一致は、類似一致よりも高いインデックスが付けられます。「ウォーキング」での検索は、「ウォーキング」が2回(ステム処理と非ステム処理)のコンテンツと「ウォーク」が1回(ステム処理のみ)のコンテンツに一致します。
  • ステム可能な用語での検索が、元の正確な用語*を含むコンテンツと一致しないという厄介なケースがないことが保証されます。

私が理解しているように、SolrがDrupalの外で使用される場合、これは通常、ステミングされる各フィールドのSolrスキーマファイルに<copyfield>宣言をハードコーディングすることによって行われます。


(この質問のために、Search API Solr検索インデックス付けノードを想定し、フィールドTitle、Body、Teaser、Notesという名前の1つのカスタムフィールドとしてフルテキストとして処理します)


問題:WithDrupalSearch APIモジュールSearch API Solr 、フィールドはDrupalで動的に構成されます-にハードコードされるのではなくSolr schema.txtファイル。2つのアプローチをうまく連携させる方法は明確ではありません。

schema.txtファイルのcopyfieldに基づいてフィールド名をハードコードするよりも、ステムされたコンテンツとステムされていないコンテンツにインデックスを付けるより優れた、Drupalフレンドリーな方法はありますか?

ハードコーディングが答えである場合、どの名前を使用する必要がありますか?名前空間の問題を回避するためにどのような注意を払う必要がありますか?


Drupalの外でSolrを使用する別の一般的なアプローチは、すべてのフルテキストフィールドの複合フィールドを作成し、フルテキストではなくstringとして扱います。これにより、フィルターをバイパスし、検索された単語をテキストに表示されているとおりにモップアップしてブーストします。SearchAPIには2つの機能があります。これが期待できるワークフローの下で、Aggregated fieldsComplete entity view-but(私が知る限り)両方ができるのはフルテキストとしてインデックスを付けるため、通常のフィールドと同じように語幹処理されます。


Search API Solrに固有のこれについて何も表示されません。私が見ることができる最も近いものは このD8コア検索の問題 ですが、それはかなり異なります。このようなSearch APIに関する情報は見つかりません。


**(たとえば、ステミングを使用すると、「unravelling」での検索は「unravelling」を含むコンテンツと一致しませんが、「unravel」での検索は一致します。「unravel」に絞り込まれていますが、何らかの理由で'unravelling'をステム 'unravel'の有効な拡張として認識します。'Unpublished 'は別の例です(非公開の一致、非公開はそうではありません)同様の言語固有のステミングの問題に関するさまざまなレポートを目にしました。標準的なアプローチであるとは言え、Drupalでこれを行うための明確な方法はありません)*


Search API Solrキューのサポート問題 (そうです、このようなクロスポストは そうです、実際にメンテナの生活を楽にするために推奨されます

良い質問です。また、Apache Solr IntegrationとSearch API Solrの両方の機能リクエストとして、ある時点で取り上げられるはずのトピックもあります。ステム処理されたコンテンツとステム処理されていないコンテンツの両方を検索すると、結果が大幅に向上することがよくあります。

Search API Solrの場合、モジュールにバンドルされているschema.xmlを変更せずにこれを行う方法はありません。ただし、ステミングを使用しており、バンドルされたスキーマではデフォルトでステミングが有効になっていないため、おそらくすでにご存じでしょう。

多くのcopyField定義なしでこれを行うための鍵は、dynamicFieldとcopyFieldの組み合わせを使用することです。また、2つの異なるfieldType定義も必要です。1つは非ステム化テキスト用で、もう1つはステム化テキスト用です。

次の手順を試してください。

  1. _<fieldType name="text">_の定義全体を_<fieldType name="stemmed_text">_として複製し、SnowballPorterFilterFactoryフィルターのコメントを外します。
  2. この新しいfieldTypeを使用してdynamicField定義を追加します。データを保存する必要はなく、インデックスを作成するだけです。例:_<dynamicField name="stemmed_*" type="stemmed_text" termVectors="true" stored="false" />_
  3. すべてのテキストフィールドを対応する語幹テキストフィールドにコピーするワイルドカードcopyField定義を追加します。例:_<copyField source="t_*" dest="stemmed_*" />_
  4. 再インデックス。
  5. 検索するすべての語幹フィールドのSolrクエリに「qf」パラメーターを追加します。これは、hook_search_api_solr_query_alter()を使用して行うことができます。すべてのテキストフィールドが必要な場合は、「t_」で始まるフィールド名を検索できます。

ボーナス:時には、より正確な結果を最初に表示するために、ステム化されていないフィールドに対する一致を後押しすることが役立つ場合があります。 qf param のフィールド名にブーストファクターを追加できます。

ボーナス#2pf param ( "phrase field")は、完全一致をブーストする別の良い方法です。これにより、用語がユーザーの入力と同じ順序である結果を優先できます。

Apache Solr統合モジュール:

Apachesolr.moduleを使用する場合、schema.xmlを変更せずに、stemmed/unstemmedの両方に対するマッチングを実行できます。バンドルされたスキーマは多くのdynamicFieldsを含み、非常に柔軟です。デフォルトでは、検索可能なフィールドはステミングされます。 hook_apachesolr_index_documents_alter()でコンテンツフィールドをステム化されていないdynamicFieldsにコピーし、hook_apachesolr_query_alter()を介してこれらのフィールドの「qf」パラメーターを追加するだけです。

9
milesw

以下が元の問題に対する完全で十分な解決策かどうかはわかりませんが、とにかく投稿します。多分それは役に立つでしょう。

Hook_entity_property_info()を使用してフィールドのプロパティを定義してから、このプロパティを異なる設定で元のフィールドの複製としてインデックスに登録できます。

例えば。プロパティを「フルテキスト」としてインデックス付けした「list_text」フィールドと、ファセットでより有用な「文字列」として元のフィールドに対してこれを実行しました。

0
donquixote