I want to serve my users the most relevant and best results. For example, I'm rewarding records that have a big title, description, attached photos, etc. For context: the records are bicycle routes, having routepoints (coordinates) and metadata like photos, reviews, etc.
Now, I have indexed these records using Hibernate
and then I search within the index using Lucene
in Hibernate Search
. To score my results, I build queries based on the document properties and boost them (using boostedTo()
) in a should
BooleanJunction clause
:
bj.should(qb.range().onField("descriptionLength").above(3000).createQuery()).boostedTo(3.0f);
bj.should(qb.range().onField("views.views").above(5000).createQuery()).boostedTo(3.0f);
bj.should(qb.range().onField("nameLength").above(20).createQuery()).boostedTo(1.0f);
bj.should(qb.range().onField("picturesLength").above(0).createQuery()).boostedTo(5.0f);
bj.should(qb.keyword().onField("routePoints.poi.participant").matching("true").createQuery()).boostedTo(10.0f);
To try and disable Lucene's scoring, I have overridden the DefaultSimilarity
class, set all the comparing to 1.0f score and enabled it via Hibernate config:
public class IgnoreScoringSimilarity extends DefaultSimilarity {
@Override
public float idf(long docFreq, long numDocs) {
return 1.0f;
}
@Override
public float tf(float freq) {
return 1.0f;
}
@Override
public float coord(int overlap, int maxOverlap) {
return 1.0f;
}
@Override
public float lengthNorm(FieldInvertState state) {
return 1.0f;
}
@Override
public float queryNorm(float sumOfSquaredWeights) {
return 1.0f;
}
}
Hibernate config:
<property name="hibernate.search.default.similarity" value="com.search.IgnoreScoringSimilarity"/>
This approach works for 90% of the time, however, I am still seeing some weird results that seem to be out of place. The pattern I recognize is that these routes (documents) are very large in size. A normal route has about 20-30 routepoints, however these out-of-place results have 100-150. This leaves me to believe that default Lucene scoring is still happening (scoring higher because of document size).
Am I doing something wrong in disabling Lucene's scoring? Could there be another explanation?
document.setBoost()
on the indexer to set a custom value, based on the number of routepoints, and check the results. Something likesetBoost(100/routepoints_count)
, or some exponential function. – Berkey