2015-03-19 57 views
0

使用Lucene,我正在對包含文檔,查詢和相關文件(qrels)的相當經典的測試集進行一些評估。 qrels告訴我們哪些文檔應該由lucene返回爲與特定查詢相關,因此可以測量lucenes搜索質量(使用一些參數,但現在不重要)。Lucene外部文檔Id偏離內部索引docId

我的問題是:測試集合中的文檔(即TIME集合)有它們自己的文檔ID--但是,這些文檔可能有差距(例如:TIME集合包含423個文檔,但始於文檔ID 17並結束ID 563)。文檔ID被索引並存儲爲IntField。

document.add(new IntField(Constants.INDEX_ID_FIELD, testDocument.getId(),Field.Store.YES)); 

不過,我可以(甚至應該)不使用IndexReader.getTermVectors()方法,通過他們的外部ID訪問文件,因爲使用Lucene的這種方法裏面的內部的docId不匹配外部ID(因爲差距)。我得到一個錯誤,說「docID必須> = 0和< maxDoc = 423(得到docID = 520)」。

什麼是使lucene正確訪問文檔520以通過內部docId爲文檔調用getTermVectors方法的首選方法? 我試圖得到正確的文件是這樣的:

IndexSearcher searcher = myTestRunner.indexSearcher; 
TermQuery query = new TermQuery(new Term(Constants.INDEX_ID_FIELD, String.valueOf(docIdx))); 
TopDocs topdocs = searcher.search(query, 1); 
ScoreDoc[] treffer = topdocs.scoreDocs; 
int docId = treffer[0].doc; 
Terms vector = myTestRunner.indexReader.getTermVector(docId, "content"); 
// ... some more code follows 

但是,文件似乎並沒有被發現(但它是在指數 - 用盧克選中)。我總是得到:

2015-03-19 12:23:25 ERROR ControlView:1002 - 0 java.lang.ArrayIndexOutOfBoundsException: 0 
at de.janjan.irtool.querygenerator.QueryGenerator.getFrequencies(QueryGenerator.java:335) 

我的下一個想法是讓IntField正常的領域,但也許我完全是在錯誤的軌道在這裏?任何幫助woukd將不勝感激。

非常感謝! Jan

回答

0

關於Lucene的內部DocID(即您在ScoreDoc.doc中看到的內容),您不應將其用作外部ID。他們可以在沒有警告的情況下更改(特別是如果您更新文檔)。

數字字段(如IntField)不是以純文本形式編入索引,而是編碼到可以高效搜索數字區域的表單中。要搜索他們,你應該使用NumericRangeQuery,如:

Query query = NumericRangeQuery.newIntRange(Constants.INDEX_ID_FIELD, docIdx, docIdx, true, true); 

但是,如果這是一個典型的id字段,我不會用一個IntField。大多數時間這樣的標識符是爲了方便而由數字組成的,而不是因爲它們代表有意義的數字。通常,如果在數字範圍內搜索該字段沒有意義,則最好使用StringField代替。

+0

非常感謝 - 懂了!我嘗試了NumericRangeQuery的IntField方法,它工作正常!我也會在稍後嘗試使用StringField。 – JanJanJan 2015-03-21 16:35:08