Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Lucene:带有前缀查询的分数计算_Java_Lucene_Lucene.net - Fatal编程技术网

Java Lucene:带有前缀查询的分数计算

Java Lucene:带有前缀查询的分数计算,java,lucene,lucene.net,Java,Lucene,Lucene.net,我对带有前缀查询的分数计算有问题。为了更改每个文档的分数,在将文档添加到索引中时,我使用了setBoost来更改文档的提升。然后我创建PrefixQuery进行搜索,但结果没有根据boost进行更改。对于前缀查询,setBoost似乎完全不起作用。请在下面检查我的代码: @Test public void testNormsDocBoost() throws Exception { Directory dir = new RAMDirectory(); IndexWriter

我对带有前缀查询的分数计算有问题。为了更改每个文档的分数,在将文档添加到索引中时,我使用了setBoost来更改文档的提升。然后我创建PrefixQuery进行搜索,但结果没有根据boost进行更改。对于前缀查询,setBoost似乎完全不起作用。请在下面检查我的代码:

 @Test
 public void testNormsDocBoost() throws Exception {
    Directory dir = new RAMDirectory();
    IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_CURRENT), true,
            IndexWriter.MaxFieldLength.LIMITED);
    Document doc1 = new Document();
    Field f1 = new Field("contents", "common1", Field.Store.YES, Field.Index.ANALYZED);
    doc1.add(f1);
    doc1.setBoost(100);
    writer.addDocument(doc1);
    Document doc2 = new Document();
    Field f2 = new Field("contents", "common2", Field.Store.YES, Field.Index.ANALYZED);
    doc2.add(f2);
    doc2.setBoost(200);
    writer.addDocument(doc2);
    Document doc3 = new Document();
    Field f3 = new Field("contents", "common3", Field.Store.YES, Field.Index.ANALYZED);
    doc3.add(f3);
    doc3.setBoost(300);
    writer.addDocument(doc3);
    writer.close();

    IndexReader reader = IndexReader.open(dir);
    IndexSearcher searcher = new IndexSearcher(reader);

    TopDocs docs = searcher.search(new PrefixQuery(new Term("contents", "common")), 10);
    for (ScoreDoc doc : docs.scoreDocs) {
        System.out.println("docid : " + doc.doc + " score : " + doc.score + " "
                + searcher.doc(doc.doc).get("contents"));
    }
} 
输出为:

 docid : 0 score : 1.0 common1
 docid : 1 score : 1.0 common2
 docid : 2 score : 1.0 common3

这是预期的行为。以下是Lucene creator的Doug Cutting的解释:

PrefixQuery相当于包含所有匹配 前缀,因此通常包含许多术语。有这么大的 查询时,匹配的文档可能包含较少的查询词和 这场比赛因此变得更弱了

阅读引用的内容

对于Lucene,通常最好只将分数用作一组文档中相关性的相对度量。分数的绝对值将根据许多因素而变化,因此不应按原样使用

更新

切割的解释是指Lucene的旧版本。因此,bajafresh4life的答案是正确的。

默认情况下,PrefixQuery会重写查询以使用ConstantCoreQuery,这会为每个匹配文档提供1.0分。我认为这是为了使PrefixQuery更快。所以你的助推被忽略了

如果希望增强在PrefixQuery中生效,则需要在PrefixQuery实例上使用SCORING_BOOLEAN_QUERY_REWRITE常量调用setRewriteMethod()。看


要进行调试,可以使用searcher.explain()。

更改重写方法

Bajafresh4life建议调用
setRewriteMethod
。然而,这不是你在Lucene.Net中改变的方式。下面是如何在C#中执行此操作:

默认情况下,每个
PrefixQuery
QueryParser
NewPrefixQuery
方法返回,如下所示:

protected internal virtual Query NewPrefixQuery(Term prefix)
{
    return new PrefixQuery(prefix) { RewriteMethod = multiTermRewriteMethod };
}
在实例化解析器后,可以使用
QueryParser.multi-termRewriteMethod
set
属性更改此设置,如下所示:

var parser = new QueryParser( Version.LUCENE_30, field, analyzer );
parser.MultiTermRewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
请注意,这也将更改其他查询的行为,而不仅仅是前缀查询。要仅影响前缀查询,可以将
QueryParser
子类化并重写
NewPrefixQuery
,以便返回的
PrefixQuery
的构造函数使用您选择的重写方法

使用哪种重写方法

不过,这似乎并没有为我解决问题。实际上,我使用
多项查询时运气更好。常量\u分数\u布尔值\u查询\u重写
。在对这种方法的描述中,它说

与评分\u布尔\u查询\u重写类似,除了不计算分数之外。相反,每个匹配的文档都会收到一个等于查询提升的恒定分数

但这可能是因为我还对
PrefixQuery
进行了子类化,并重写了
ReWrite
,以分配我想要的分数作为奖励


经过大量的调试,我最终发现,当我试图使用
评分\u BOOLEAN\u QUERY\u REWRITE
时,
DefaultSimilarity.QueryNorm
权重.Normalize
中使用它返回的值时,它干扰了我的分数,这在
Query.Weight

中调用。注意,在字段级别使用setBoost时,这似乎也适用。i、 除非按照此处所述更改重写方法,否则e PrefixQuery将显示为忽略字段提升。