You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@lucene.apache.org by Paul Taylor <pa...@fastmail.fm> on 2013/02/19 12:42:54 UTC
What replaces the computeNorm method in DefaultSimilarity in 4.1
now that the method is final
What replaces the computeNorm method in DefaultSimilarity in 4.1
Ive always subclassed DefaultSimilarity to resolve an issue whereby when
document has multiple values in a field (because has one-many
relationship) its score worse then a document which just has single
value but the computeNorm()
method has gone, but when I tried to rewrite the method for 4.1 as follows
public void computeNorm(FieldInvertState state, Norm norm) {
if (state.getName().equals("alias")) {
if(state.getLength()>=3) {
norm.setFloat(state.getBoost() * 0.578f);
}
else {
super.computeNorm(state, norm);
}
}
else {
super.computeNorm(state, norm);
}
}
I found it was final so what should I do.
3.6 Code:
package org.musicbrainz.search.analysis;
import org.apache.lucene.index.FieldInvertState;
import org.apache.lucene.search.similarities.DefaultSimilarity;
/**
* Calculates a score for a match, overridden to deal with problems
with alias fields in artist and label indexes
*/
public class MusicbrainzSimilarity extends DefaultSimilarity
{
/**
* Calculates a value which is inversely proportional to the number
of terms in the field. When multiple
* aliases are added to an artist (or label) it is seen as one
field, so artists with many aliases can be
* disadvantaged against when the matching alias is radically
different to other aliases.
*
* @return score component
*/
public float computeNorm(String field, FieldInvertState state) {
//This will match both artist and label aliases and is
applicable to both, didn't use the constant
//ArtistIndexField.ALIAS because that would be confusing
if (field.equals("alias")) {
if(state.getLength()>=3)
{
return state.getBoost() * 0.578f; //Same result as
normal calc if field had three terms the most common scenario
}
else {
return super.computeNorm(field,state);
}
}
else
{
return super.computeNorm(field,state);
}
}
/**
* This method calculates a value based on how many times the
search term was found in the field. Because
* we have only short fields the only real case (apart from rare
exceptions like Duran Duran Duran) whereby
* the term term is found more than twice would be when
* a search term matches multiples aliases, to remove the bias this
gives towards artists/labels with
* many aliases we limit the value to what would be returned for a
two term match.
*
* Note: would prefer to do this just for alias field, but the
field is not passed as a parameter.
* @param freq
* @return score component
*/
@Override
public float tf(float freq) {
if (freq > 2.0f) {
return 1.41f; //Same result as if matched term twice
} else {
return super.tf(freq);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org
Re: What replaces the computeNorm method in DefaultSimilarity in
4.1 now that the method is final
Posted by Paul Taylor <pa...@fastmail.fm>.
On 19/02/2013 11:42, Paul Taylor wrote:
> What replaces the computeNorm method in DefaultSimilarity in 4.1
>
> Ive always subclassed DefaultSimilarity to resolve an issue whereby
> when document has multiple values in a field (because has one-many
> relationship) its score worse then a document which just has single
> value but the computeNorm()
> method has gone, but when I tried to rewrite the method for 4.1 as
> follows
>
> public void computeNorm(FieldInvertState state, Norm norm) {
>
> if (state.getName().equals("alias")) {
> if(state.getLength()>=3) {
> norm.setFloat(state.getBoost() * 0.578f);
> }
> else {
> super.computeNorm(state, norm);
> }
> }
> else {
> super.computeNorm(state, norm);
> }
> }
>
>
>
> I found it was final so what should I do.
>
>
> 3.6 Code:
>
> package org.musicbrainz.search.analysis;
>
> import org.apache.lucene.index.FieldInvertState;
> import org.apache.lucene.search.similarities.DefaultSimilarity;
>
> /**
> * Calculates a score for a match, overridden to deal with problems
> with alias fields in artist and label indexes
> */
> public class MusicbrainzSimilarity extends DefaultSimilarity
> {
>
> /**
> * Calculates a value which is inversely proportional to the
> number of terms in the field. When multiple
> * aliases are added to an artist (or label) it is seen as one
> field, so artists with many aliases can be
> * disadvantaged against when the matching alias is radically
> different to other aliases.
> *
> * @return score component
> */
> public float computeNorm(String field, FieldInvertState state) {
>
> //This will match both artist and label aliases and is
> applicable to both, didn't use the constant
> //ArtistIndexField.ALIAS because that would be confusing
> if (field.equals("alias")) {
> if(state.getLength()>=3)
> {
> return state.getBoost() * 0.578f; //Same result as
> normal calc if field had three terms the most common scenario
> }
> else {
> return super.computeNorm(field,state);
> }
> }
> else
> {
> return super.computeNorm(field,state);
> }
> }
>
>
> /**
> * This method calculates a value based on how many times the
> search term was found in the field. Because
> * we have only short fields the only real case (apart from rare
> exceptions like Duran Duran Duran) whereby
> * the term term is found more than twice would be when
> * a search term matches multiples aliases, to remove the bias
> this gives towards artists/labels with
> * many aliases we limit the value to what would be returned for a
> two term match.
> *
> * Note: would prefer to do this just for alias field, but the
> field is not passed as a parameter.
> * @param freq
> * @return score component
> */
> @Override
> public float tf(float freq) {
> if (freq > 2.0f) {
> return 1.41f; //Same result as if matched term twice
>
> } else {
> return super.tf(freq);
> }
> }
> }
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
> For additional commands, e-mail: java-user-help@lucene.apache.org
>
>
Found it, need to override lengthNorm instead
@Override
public float lengthNorm(FieldInvertState state) {
if (state.getName().equals("alias"))
{
if(state.getLength()>=3) {
return state.getBoost() * 0.578f; //Same result as
normal calc if field had three terms the most common scenario
}
else
{
return super.lengthNorm(state);
}
}
else
{
return super.lengthNorm(state);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: java-user-unsubscribe@lucene.apache.org
For additional commands, e-mail: java-user-help@lucene.apache.org