25

より良いタイトルが見つかりませんでした。可能であれば、最終的な提案に基づいて後で変更したいと考えています。

私の問題:

音楽アーティストのデータベースを取得しました。これらは次のようになります: 「dr. dre feat. akon」、「eminem & dr. dre」、「dr. dre feat. ll cool j」、「dr. dre」、「dr. dre feat. eminem & skylar gray」 . id と name の 2 つのフィールドしかありません。

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

  • 博士。ドレ feat. エイコン
  • エミネム & Dr. ドレ
  • 博士。ドレ feat. クールなj
  • 博士。ドレ
  • ...

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

私が望むのは、次のように、最初の結果として「dr. dre」を取得し、次に他のすべての結果を取得することです。

  • 博士。dre <<-- 博士。ドレが最初
  • エミネム & Dr. ドレ
  • 博士。ドレ feat. クールなj
  • 博士。ドレ feat. エイコン
  • ...

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

ありがとう。

4

1 に答える 1

50

"dr. dre" の結果を最初に表示するには、いくつかの方法があります。長い回答で申し訳ありませんが、Solr でよくあることですが、回答は優先順位とニーズによって異なります。

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

規範

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

Solr ドキュメント wiki、または特定の Solr バージョン用にダウンロードした Solr ドキュメントで、規範について読んだり、適切な一般的なテキストfieldType構成を確認したりできます。規範に依存することの利点は、実装がかなり簡単であることに加えて、進歩的であることです。したがって、「dr. dre」はその名前が検索に 100% 一致する最も関連性の高いレコードですが、「eminem & dr. dre」は「a whole list of guys & also dr. dre」よりも関連性が高くなります。検索語は、名前の大部分を占めています。

完全に一致

完全一致は、Solr では複雑な問題です。これは主に、さまざまな程度の「正確さ」が存在するためであり、実際には完全一致が望ましいことはめったにありません。たとえば、レコードの名前が「dr. dre」の場合、「dr dre」(ピリオドなし) は正確に近いですか? 「ドクター・ドレー」ですか?「ドクター・ドレー」ですか?

完全一致検索を実装することにした場合は、おそらく次のようにコピーフィールドを設定する必要がありますschema.xml

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

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

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

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

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

<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"/>

この非常に基本的な例には、名前全体を 1 つのトークンとして保持する Keyword Tokenizer と、大文字と小文字の違いが関係ないことを確認する Lower Case Filter のみが含まれています。完全一致で他の条件を許容する場合は、fieldType の分析を変更する必要があります。

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

于 2015-03-17T16:51:04.937 に答える