Lucene 6.6.0 中的索引时间字段级别提升?

Posted

技术标签:

【中文标题】Lucene 6.6.0 中的索引时间字段级别提升?【英文标题】:Index time field level boosting in Lucene 6.6.0? 【发布时间】:2018-01-31 00:02:24 【问题描述】:

在 Lucene 6.6.0 及更高版本中,字段级索引时间提升为 deprecated。文档指出:

不推荐使用索引时间提升,请索引索引时间评分 因素到一个文档值字段中,并将它们与分数结合起来 使用例如查询时间。 FunctionScoreQuery。

以前会像这样在索引时提升字段:

    Field title = new Field(PaperDAO.LUCENE_FIELD_TITLE, titleStr, fieldType);
    title.setBoost(3.00f);
    document.add(title);

    Field authors = new Field(PaperDAO.LUCENE_FIELD_AUTHOR, StringEscapeUtils.unescapehtml4(this.getAuthorsForLucene()), fieldType);
    authors.setBoost(10.00f);
    document.add(authors);

我不明白建议的 FunctionScoreQuery 如何成为字段级提升的合适替代品,因为一个人仅在给定现有 Query 的情况下构造一个 FunctionScoreQuery 和一个 DoubleValuesSource 代表仅可能多个字段之一的提升值:

// INDEX TIME
Field title = new Field(PaperDAO.LUCENE_FIELD_TITLE, titleStr, fieldType);
document.add(title);
document.add(new FloatDocValuesField(PaperDAO.LUCENE_FIELD_TITLE + "_boost", 3.00f));

// QUERY TIME
new FunctionScoreQuery(query, DoubleValuesSource.fromFloatField(PaperDAO.LUCENE_FIELD_TITLE + "_boost"))

有人可以解释一下 Lucene >= 6.6.0 中 Field#setBoost @ index time 的适当替换吗?我们是否应该在查询时枚举所有可能的字段并应用相关的提升?如果是这样,该查询是如何构造的?

【问题讨论】:

看起来这个简单的问题没有简单的答案。同时你有解决方案吗? 【参考方案1】:

首先,您还有一些时间使用旧式索引时间提升,因为它们只会在 Lucene 7.0 中被移除 :)

转到主题,很久以前的社区decided,索引时间提升是一种复杂且难以正确处理的技术。

我认为当前的想法是 - 不是用每个字段 docvalues 字段替换每个字段的索引时间提升,而是用 docvalues 字段中的 1 个累积分数替换文档的所有索引时间提升,然后在期间使用它搜索。

请将索引时间评分因素编入文档值字段 并将它们与查询时的分数结合起来

引用来自javadoc,这只会加强我的这个想法。您可以将多个因素索引到一个字段中。

对我来说,悬而未决的问题是 - 如何将几个因素组合成 1。我希望这是要测试和验证的东西(使用乘法、求和或某种线性组合)

【讨论】:

【参考方案2】:

如果您想使用 FunctionScoreQuery 提升不同的字段,建议的方法如下(取自CustomeScoreProvider):

对于更复杂的自定义分数,请使用 lucene-expressions 库

   SimpleBindings bindings = new SimpleBindings();
   bindings.add("score", DoubleValuesSource.SCORES);
   bindings.add("boost1", DoubleValuesSource.fromIntField("myboostfield"));
   bindings.add("boost2", DoubleValuesSource.fromIntField("myotherboostfield"));
   Expression expr = javascriptCompiler.compile("score * (boost1 + ln(boost2))");
   FunctionScoreQuery q = new FunctionScoreQuery(inputQuery, expr.getDoubleValuesSource(bindings));

【讨论】:

以上是关于Lucene 6.6.0 中的索引时间字段级别提升?的主要内容,如果未能解决你的问题,请参考以下文章

利用lucene对mysql数据创建索引,提高全文检索速度

如何获取 lucene 索引中每个术语的帖子列表

Lucene字段

Lucene Search查询标记化索引中的多个值

lucene查询索引的6个步骤

03.Lucene中的常用类