Java 如何在Lucene 6中获取文档的字段规范?

Java 如何在Lucene 6中获取文档的字段规范?,java,lucene,Java,Lucene,我想计算TF-IDF分数,该分数通过字段范数标准化,用于通过Lucene找到的各种文档的字段组合_字段中的每个术语。正如您在下面的代码中所看到的,我可以得到文档字段中每个术语的术语频率,我也可以得到文档频率,但是我找不到在查询时获得该字段规范的方法。到目前为止,我发现的所有方法都依赖于只存在于旧Lucene版本中的方法,而不适用于Lucene 6。方法可能是使用,但我没有找到一种方法来获取它的实例 你知道我怎样才能得到每个文档的字段的范数吗 或者我可以使用termVector.size()替换字

我想计算TF-IDF分数,该分数通过字段范数标准化,用于通过Lucene找到的各种文档的字段组合_字段中的每个术语。正如您在下面的代码中所看到的,我可以得到文档字段中每个术语的术语频率,我也可以得到文档频率,但是我找不到在查询时获得该字段规范的方法。到目前为止,我发现的所有方法都依赖于只存在于旧Lucene版本中的方法,而不适用于Lucene 6。方法可能是使用,但我没有找到一种方法来获取它的实例

你知道我怎样才能得到每个文档的字段的范数吗

或者我可以使用termVector.size()替换字段长度吗?大小()是否考虑了 每个术语的出现或每个术语只计算一次

提前谢谢

IndexSearcher iSearcher = null;
ScoreDoc[] docs = null;
try {
   iSearcher = this.searchManager.acquire();
   IndexReader reader = iSearcher.getIndexReader();

   MultiFieldQueryParser parser = new MultiFieldQueryParser(this.getSearchFields(), this.queryAnalyzer);

   parser.setDefaultOperator(QueryParser.Operator.OR);

   Query query = parser.parse(QueryParser.escape(searchString));            

   docs = iSearcher.search(query, maxSearchResultNumber).scoreDocs;     

   for(int i=0; i < docs.length; i++) {
      Terms termVector = reader.getTermVector(docs[i].doc, COMBINED_FIELD);

      TermsEnum itr = termVector.iterator();
      BytesRef term = null;
      PostingsEnum postings = null;

      while((term = itr.next()) != null){
         String termText = term.utf8ToString();
         postings = itr.postings(postings, PostingsEnum.FREQS);
         postings.nextDoc();

         int tf = postings.freq();
         int docFreq = reader.docFreq(new Term(COMBINED_FIELD, term));
         //HERE I WANT TO GET THE FIELD LENGTH OF THE CURRENT DOCUMENT
      }
   }
} catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();         
} finally {
   try {
      this.searchManager.release(iSearcher);
   } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
}
IndexSearcher-iSearcher=null;
ScoreDoc[]文档=null;
试一试{
iSearcher=this.searchManager.acquire();
IndexReader=iSearcher.getIndexReader();
MultiFieldQueryParser parser=新的MultiFieldQueryParser(this.getSearchFields(),this.queryAnalyzer);
setDefaultOperator(QueryParser.Operator.OR);
Query=parser.parse(QueryParser.escape(searchString));
docs=iSearcher.search(查询,maxSearchResultNumber).scoreDocs;
对于(int i=0;i

另外,是否有办法直接从Lucene获取字段中每个项的TF-IDF或BM25值?Lucene在方法
org.apache.Lucene.search.similories.Similarity#computeNorm
中编制索引时,在内部计算规范,然后对其进行编码并存储在磁盘上的
.nvm
文件中。之后,在查询/评分期间,仅对其进行解码

我认为,在Lucene中以编程方式实现这一点的一种可能方法是扩展相似性类,并在索引和存储过程中以某种方式获取这些信息。在我看来,这不是最好的方式,但至少是某种方式

另一方面,
BM25Similarity
通过以下方式计算长度:

discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength();

其中
getLength()
是字段中的项数,您可以在
中迭代计算,就像您在示例中所做的那样。

那么,您想计算范数还是获得长度?实际上,我想得到Lucene在索引过程中通常计算的范数,据我所知。但是,如果不可能,我会使用长度作为代理,并使用我自己的标准1/sqrt(长度)。非常感谢您的回复!嗯,这可能是一种方式,我已经想过了,但我想我可能错过了一些东西。我的意思是,Lucene并没有一个真正稳定的API,他们在不断地改变几乎所有的东西,但我对他们为什么要删除以前提供的功能感到困惑。迭代这些术语并乘以它们的频率将是plan z,但确实,这是一种方法。但是,我认为Lucene可能会将此值存储在我也可以访问的某个位置。他们对其进行了很多更改,是的:)是的,正如我所说,Lucene将规范存储在磁盘上的.nvm文件中,因此您可能可以手动读取并解码,但这并不是Lucene API的方式,这是真的!我的意思是,我也可以在Lucene中找到读取nvm文件的代码,然后手动再次执行,但这真的很奇怪,不是吗?我想你的第二种方法将是更好(更容易,可能更快)获取这些信息的方法。顺便说一下,size()只对每个标记计数一次,因此不会返回此字段的完整长度。