これを行う最善の方法は、SpellChecker オブジェクトでカスタマイズされた Comparator を使用することだと思います。
ここで、デフォルトのコンパレータのソース コードを確認してください。
http://grepcode.com/file/repo1.maven.org/maven2/org.apache.lucene/lucene-spellchecker/3.6.0/org/apache/lucene/search/spell/SuggestWordScoreComparator.java?av=f
2 つの文字列を比較するために使用するアルゴリズムが既にある場合は、非常に単純なものを簡単に拡張できます。
次に、 SpellChecker.SetComparatorでコンパレータを使用するように設定できます
以前の質問で、これに Filter を使用する可能性について言及したと思いますが、それは本当に正しい方法ではないと思います。
編集 - -
実際、3.0.3 では Comparator は使用できないため、StringDistanceオブジェクトを介してスコアリングにアクセスする必要があると思います。Comparator は、スコアリングが既に適用されており、好きなことを行うために渡されるため、より優れています。StringDistance の拡張は、スコアの一部としてルールを適用する必要があるため、少し具体的ではない場合があります。
デフォルトの StringDistance 実装であるLevensteinDistance (ソース コード)を拡張したいと思うかもしれませんが、もちろん、JaroWinklerDistanceも自由に試してみてください。アルゴリズムにあまり詳しくありません。
主に、標準 (親) 実装の getDistance 呼び出しからベースライン距離を取得した後、getDistance をオーバーライドしてスコアリング ルールを適用する必要があります。
私はおそらく次のようなものを実装します(ヘルパーメソッドがあると仮定するとboolean isPermutation(String, String)
:
class CustomDistance() extends LevensteinDistance{
float getDistance(String target, String other) {
float distance = super.getDistance();
if (isPermutation(target, other)) {
distance = distance + (1 - distance) / 2;
}
return distance;
}
}
順列である結果の 1 に近い半分のスコアを計算するには (つまり、デフォルトのアルゴリズムが距離 = .6 を与えた場合、これは距離 = .8 を返します)。返される距離は 0 から 1 の間である必要があります。私の例は、可能なスコアリングの 1 つのアイデアにすぎませんが、アルゴリズムを多少調整する必要がある可能性があります。すべての順列に対して単純に 1.0 を返すことには注意が必要です。これは、'weiss' で検索するときに 'weis' よりも 'isews' を優先することが確実であり、異なる順列の近さをソートする機能も失うためです ('その場合、isews と wiess は weiss と等しく一致します)。
カスタム StringDistance を取得したら、コンストラクターを介して、または SpellChecker.setStringDistance を使用して SpellChecker に渡すことができます。