Lucene スコアリングをオーバーライドできます。
org.apache.lucene.search.DefaultSimilarityを拡張して、カスタム スコアリング アルゴリズムを定義します。
スコアリングのより複雑な要素が結果に影響を与えないように、DefaultSimilarity の多くのメソッドは、おそらく idf (1 を返すだけ) のように単にスタブしたいでしょう。
次に、solr の schema.xml に行を追加し、次のようにスコアリング クラスを使用するように構成します。
<similarity class="com.mycompany.MySimilarity" />
スコアリングの仕組みに関する情報が記載されたページを次に示します。ここを確認してください: Lucene Scoring。カスタム機能の追加に関するいくつかのリソースもあります。これは、おそらく使用可能な Similarily クラスをまとめるのに役立ちます。
ただし、正直なところ、特に Lucene/Solr を初めて使用する場合は、デフォルトのスコアリングを使用して経験を積んだほうがよいでしょう。それは非常にうまく機能し、それを捨てることで多くの貴重な機能を削除します.
編集:
これは、Similarity を実装するための可能な (きれいではありませんが) 方法を提供することに注意してください。さらに下を見て、別の方法を探します。カスタムの類似性は引き続き必要ですが、それはより単純なものです。
さて、ここでそれを突き刺します。私はそれをテストしていませんが (実際に今はそうする立場にありません)、おそらく正しい方向にあなたを向けるでしょう.
これを実現する最も簡単な方法は、用語の長さをエンコードする各フィールドのノルムを格納することです。これを行うには、computeNorm をオーバーライドし、2 番目の引数から取得した長さの逆数を返します。
指定した正確なスコアを計算するには、一致するクエリ用語またはその長さにアクセスする必要があります。どちらも本当に簡単ではありません。方法を見つけるか、その値を類似度クラスに手動で渡すことができます。指定した順序で値を取得する必要があるだけなので、要件を示す別の方法は、「最短から最長への順序付け」です。これはすでにcomputeNormで達成しています。
次に、残りをスタブするだけで、次の行に沿った結果が得られます。
float computeNorm(String field, FieldInvertState state) {
int length = state.getOffset() - state.getPosition();
return 1.0 / (float)length;
}
float coord(int overlap, int maxOverlap) {
return 1;
}
float idf(int docFreq, int numDocs) {
return 1;
}
float tf(float freq) {
return 1;
}
float queryNorm(float sumOfSquaredWeights) {
return 1;
}
float sloppyFreq(int distance) {
return 1;
}
float lengthNorm(string fieldName, int numTerms) {
return 1;
}
注: ノルムはドキュメントのインデックス作成時に計算されるため、有効にするには、ドキュメントを挿入するときにこの類似度を使用する必要があります。クエリ時間は標準を設定するには遅すぎます。また、圧縮のため、非常に近似しています。
より簡単な方法(おそらく):
考えてみると、短いものから長いものへとソートするだけで同じ順序が得られるため、新しいSimilarityクラスの複雑さなしにこれを行うことができます。ドキュメントを追加するときは、フィールド レベルのブーストを適用するだけで、同じことを実現できます。これらの各用語を 1/長さ、または同様の方法でブーストするだけです。
abcde を挿入すると、フィールドに 1/5 のブーストが適用されます。
それができたら、'term:abc*^3' のようにクエリを実行することもできます。これにより、前に示したパーセンテージ スコアを取得できます (クエリ タームが 1 つだけで、どちらの方法でも結果はほとんど同じですが)。
このようなブーストを使用してスコアを付ければ、CustomSimilarity のすべてをスタブ化できるはずです。'idf' と 'tf' はおそらく、この場合のオーバーライドについて本当に心配する必要があるすべてです。