【发布时间】:2015-08-22 21:37:36
【问题描述】:
我想为我的用户提供最相关和最好的结果。例如,我奖励具有大标题、描述、附加照片等的记录。对于上下文:记录是自行车路线,具有路线点(坐标)和照片、评论等元数据。
现在,我使用Hibernate 为这些记录编制了索引,然后在Hibernate Search 中使用Lucene 在索引中进行搜索。为了给我的结果打分,我根据文档属性构建查询并在should BooleanJunction clause 中提升它们(使用boostedTo()):
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);
为了尝试禁用 Lucene 的评分,我重写了 DefaultSimilarity 类,将所有比较设置为 1.0f 分数并通过 Hibernate 配置启用它:
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;
}
}
休眠配置:
<property name="hibernate.search.default.similarity" value="com.search.IgnoreScoringSimilarity"/>
这种方法在 90% 的情况下都有效,但是,我仍然看到一些奇怪的结果,似乎不合适。我认识到的模式是这些路线(文档)的大小非常大。一条正常的路线大约有 20-30 个路线点,但是这些不合适的结果有 100-150 个。这让我相信默认的 Lucene 评分仍在发生(由于文档大小而得分更高)。
我在禁用 Lucene 的评分时做错了什么吗?能不能有别的解释?
【问题讨论】:
-
不是一个答案,而是一个考虑:我不会禁用 Lucene 的默认评分,但会在索引阶段工作。我会为您的文档构建一个自定义索引器,为大文档设置(减少)提升;您可以在索引器上调用
document.setBoost()以根据路由点的数量设置自定义值,并检查结果。setBoost(100/routepoints_count)之类的东西,或者某种指数函数。 -
感谢您的评论!但是,通过考虑路由点数,这是否仍然会(尽管很小)增加文档大小?这就是我不想要的,因为对于我们的评分系统,一条路线有 2 或 200 个路线点并不重要,它应该只通过它的元数据进行评分。
-
是的,那会,但是由于您已经在用大的因素增加文档,我认为这并不重要。你真的需要索引路由点吗?您可以添加索引器的 sn-p 以了解索引的内容吗?
标签: java hibernate indexing lucene hibernate-search