首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >增加文档Lucene 8的权重

增加文档Lucene 8的权重
EN

Stack Overflow用户
提问于 2019-11-04 21:23:33
回答 2查看 698关注 0票数 1

我目前正在使用Lucene 8为大学开发一个小型搜索引擎。我以前就已经建好了,但是没有给文档施加任何权重。

现在我需要添加文档的PageRanks作为每个文档的权重,并且我已经计算了PageRank值。如何在Lucene 8中为Document对象(而不是查询术语)添加权重?我在网上找到了很多解决方案,但它们只适用于较早版本的Lucene。示例源

下面是我的(更新的)代码,它从File对象生成Document对象:

代码语言:javascript
复制
public static Document getDocument(File f) throws FileNotFoundException, IOException {
    Document d = new Document();

    //adding a field
    FieldType contentType = new FieldType();
    contentType.setStored(true);
    contentType.setTokenized(true);
    contentType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
    contentType.setStoreTermVectors(true);

    String fileContents = String.join(" ", Files.readAllLines(f.toPath(), StandardCharsets.UTF_8));
    d.add(new Field("content", fileContents, contentType));

    //adding other fields, then...

    //the boost coefficient (updated):
    double coef = 1.0 + ranks.get(path);
    d.add(new DoubleDocValuesField("boost", coef));

    return d;

}

我目前的方法的问题是,我需要一个CustomScoreQuery对象来搜索文档,但在Lucene 8中是不可用的。而且,在我用Lucene 8编写了所有代码之后,我不想现在降级到Lucene 7。

编辑:

经过一些(长时间的)研究后,我在每个保存boost的文档中添加了一个DoubleDocValuesField (参见上面更新的代码),并按照@EricLavault的建议使用FunctionScoreQuery进行搜索。但是,现在我所有的文档都有一个分数,不管是什么查询!如何解决这个问题?这是我的搜索功能:

代码语言:javascript
复制
public static TopDocs search(String query, IndexSearcher searcher, String outputFile) {
    try {
        Query q_temp = buildQuery(query); //the original query, was working fine alone

        Query q = new FunctionScoreQuery(q_temp, DoubleValuesSource.fromDoubleField("boost")); //the new query
        q = q.rewrite(DirectoryReader.open(bm25IndexDir));
        TopDocs results = searcher.search(q, 10);

        ScoreDoc[] filterScoreDosArray = results.scoreDocs;
        for (int i = 0; i < filterScoreDosArray.length; ++i) {
            int docId = filterScoreDosArray[i].doc;
            Document d = searcher.doc(docId);

            //here, when printing, I see that the document's score is the same as its "boost" value. WHY??
            System.out.println((i + 1) + ". " + d.get("path")+" Score: "+ filterScoreDosArray[i].score);
        }

        return results;
    }
    catch(Exception e) {
        e.printStackTrace();
        return null;
    }
}

//function that builds the query, working fine
public static Query buildQuery(String query) {
    try {
        PhraseQuery.Builder builder = new PhraseQuery.Builder();
        TokenStream tokenStream = new EnglishAnalyzer().tokenStream("content", query);
        tokenStream.reset();

        while (tokenStream.incrementToken()) {
          CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class);
          builder.add(new Term("content", charTermAttribute.toString()));
        }

        tokenStream.end(); tokenStream.close();
        builder.setSlop(1000);
        PhraseQuery q = builder.build();

        return q;
    }
    catch(Exception e) {
        e.printStackTrace();
        return null;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-07 21:36:33

关于我编辑的问题(boost值完全代替搜索分数,而不是增加),下面是文档FunctionScoreQuery的看法:

包装另一个查询并使用DoubleValuesSource替换或修改包装查询的得分的DoubleValuesSource的查询。

那么,它什么时候替换,什么时候修改呢?

结果,我所使用的代码完全是用boost值替换分数:

代码语言:javascript
复制
Query q = new FunctionScoreQuery(q_temp, DoubleValuesSource.fromDoubleField("boost")); //the new query

我需要做的是使用函数boostByValue,它修改搜索分数(通过将分数乘以boost值):

代码语言:javascript
复制
Query q = FunctionScoreQuery.boostByValue(q_temp, DoubleValuesSource.fromDoubleField("boost"));

现在起作用了!谢谢你的帮助!

票数 1
EN

Stack Overflow用户

发布于 2019-11-07 11:48:51

Lucene 6.5.0开始:

索引时间提升是不可取的。作为替代,索引时间评分因素应该被索引到文档值字段中,并在查询时使用例如组合。FunctionScoreQuery。(阿德里安·格兰德)

建议不要使用索引时间提升,而是对评分因素进行编码(即。将长度归一化因子)转换为doc值字段。(请参阅卢塞尼-6819)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58701267

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档