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

时间:2017-09-03 18:36:01

标签: java lucene

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

您是否知道如何为每个文档获取字段COMBINED_FIELD的规范?

或者我可以使用termVector.size()作为字段长度的替换吗? 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();
   }
}

或者,有没有办法直接从Lucene获取字段的每个术语的TF-IDF或BM25值?

1 个答案:

答案 0 :(得分:1)

Lucene在方法org.apache.lucene.search.similarities.Similarity#computeNorm中编制索引期间的规范,然后对其进行编码并将其存储在.nvm文件的磁盘上。之后,在查询/评分期间,它仅被解码。

我认为,在Lucene中以编程方式执行此操作的一种可能方法是扩展Similarity类,并在索引和某处存储时以某种方式获取此信息。对我来说听起来不是最好的方式,但至少是一些东西。

另一方面,BM25Similarity以这种方式计算长度:

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

其中getLength()是字段中的字词数,您可以通过在while中迭代来计算,就像在示例中一样。