web-dev-qa-db-ja.com

完全一致を含むテキストに対するSOLR完全一致ブースト

良いタイトルが見つかりませんでした。可能であれば、将来の変更を考えて後で変更したいと思っています。

私の問題:

音楽アーティストのデータベースを入手しました。これらは、「dr。dre feat。akon」、「eminem&dr。dre」、「dr。dre feat。ll cool j」、「dr。dre」、「dr。dre feat。eminem&skylar grey」のようになります。 。 IDと名前の2つのフィールドしかありません。

デフォルトのスキーマsolrコアで、「q = dr。dre」というクエリを実行します。結果は問題ありませんが、完全ではありません。次のようになります。

  • 博士。ドレ偉業。エイコン
  • エミネムと博士ドレ
  • 博士。ドレ偉業。かっこいい
  • 博士。ドレ
  • ...

彼らはまったく同じスコアを得たことに注意してください。

私が欲しいのは、最初の結果として「dr。dre」があり、次に他のすべてのものが次のようになることです。

  • 博士。 dre <<-dr。dreが最初
  • エミネムと博士ドレ
  • 博士。ドレ偉業。かっこいい
  • 博士。ドレ偉業。エイコン
  • ...

どうすればこれを達成できますか? (フィルター、トークナイザー、フィールドのコピーなどは問題ではありません。他のフォーラムで提案されているように、solr内のコードを変更することはできません)

ありがとう。

20
BogdanM

「dr。dre」の結果を最初に表示するには、いくつかの方法があります。長い回答をお詫びしますが、Solrで頻繁に発生するように、回答は優先度とニーズによって異なります。

これはおそらく冗長ですが、各結果のスコアが表示されていることを確認することから始めたいと思います。あなたの質問はこれを完全に明確にしませんでした。クエリを作成するときは、結果をスコアで降順にソートするようにSolrに明示的に指示する必要がありますが、これはsolrconfig.xmlで設定できます。あなたはすでにこれを行っていると思いますが、念のため、次のようなクエリを試すことができます:q="dr. dre"&fl=*,score&sort=score desc。これにより、各結果の計算されたスコアが表示され、スコアが最も高い結果が最初にソートされます。

規範

規範は、Solrでかなり自然に機能する柔軟なオプションです。 nameフィールドには、typeエントリにマップされるfieldType値が含まれているはずです。 fieldTypeにはおそらくclass="solr.TextField"が含まれている必要があり、omitNorms="true"が含まれていてはなりません。名前フィールドの規範を明示的に省略しない限り、Solrは、ドキュメントのスコアを計算するときに、名前のどの程度が検索用語と一致するか、および検索用語が名前で何回一致するかを考慮します。名前の単語の100%が検索に一致するため、「dr。dre」が最も高いスコアになります。

Solrのドキュメントwiki で、または特定のSolrバージョンのダウンロードされたSolrのドキュメントで、規範について読み、優れた一般的なテキストfieldType構成を確認できます。規範に依存することの利点は、実装がかなり簡単であることに加えて、進歩的であるということです。したがって、 "dr。dre"はmost関連レコードであり、名前の100%が検索に一致しますが、 "eminem&dr。dre"も検索語句が名前の割合の大部分を占めるため、「みんなのリスト全体と博士ドレ」よりも関連性が高い

完全に一致

厳密な一致はSolrの複雑な問題です。これは、主に「正確さ」の程度がさまざまであり、実際の正確な一致が現実の世界で望ましいことはほとんどないためです。たとえば、レコードの名前が "dr。dre"の場合、 "dr dre"(ピリオドなし)は正確に近いですか? 「ドクター・ドレー」ですか? 「ドクタードレ」ですか?

完全一致検索を実装する場合は、schema.xmlにコピーフィールドを設定することをお勧めします。

<copyField source="name" dest="exactName"/>

次に、両方のフィールドを一緒に検索します。これを行う方法は、使用しているクエリパーサーによって異なります。 standard/lucene クエリパーサーを使用している場合は、OR searching(eg q=name:"dr. dre" OR exactName:"dr. dre"^4))を使用してクエリを設定する必要があります。検索語の後の "^ 4"は、クエリの他の場所での一致の4倍の重要性/関連性で一致します。 Dismax または Extended Dismax クエリパーサーを使用している場合、新しい qf フィールドにアクセスできます。これにより、フィールドのリストを提供できます。検索に使用し、いくつかを他よりも重要なものとして設定します。たとえば、qf=exactName^4 name&q="dr. dre"はSolrに両方のフィールドで「dr。dre」をチェックするように指示しますが、exactNameフィールドの一致は4回と見なします名前フィールドの1つとして関連しています(これが機能する場合は、デフォルトのqfsolrconfig.xmlに設定できるため、すべてのクエリで再定義する必要はありません)。

これにより、exactNameフィールドのfieldTypeは未定のままになります。完全に正確な一致のみが機能し、大文字と小文字や句読点の違いによって一致が完全ではなくなると思われる場合は、exactNameフィールドを文字列として設定できます。

<field name="exactName" type="string" indexed="true" stored="false" multiValued="false"/>

しかし、より正確には、「正確」と見なされるものにいくつかのバリエーションを許可する必要があります。その場合、おそらく Keyword Tokenizer を使用して、新しいfieldTypeを作成する必要があります。正確な名前を複数のインデックス付きトークンに分割しませんが、単一のトークンとして保持します。例えば:

<fieldType name="exactish" class="solr.TextField">
  <analyzer>
   <tokenizer class="solr.KeywordTokenizerFactory"/>
   <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer> 
</fieldType>

<field name="exactName" type="exactish" indexed="true" stored="false" multiValued="false"/>

この非常に基本的な例には、名前全体を単一のトークンとして保持するキーワードトークナイザーと、大文字と小文字の違いが関係しないことを確認する小文字フィルターのみが含まれています。完全一致で他の条件を許容する場合は、fieldTypeの分析を変更する必要があります。

重要:文字列フィールド、またはキーワードトークナイザーを含むテキストフィールドに対して検索する場合は、送信する検索がSolrは常に引用符で囲みます(つまり、フレーズ検索)。それ以外の場合、検索はフィールドと比較される前に個々の用語に分割され、インデックス付きフィールド全体に一致するoneはありません。これにより、値にスペースが含まれていない場合を除いて、フィールドで一致がまったく検索されない可能性があります。 Normsを使用して、より標準的なトークン化でtextFieldの関連性を制御する場合、これは問題ではありません。

36
frances