Lucene外部文档Id偏离内部索引docId

时间:2015-03-19 11:28:07

标签: java indexing lucene

使用Lucene,我正在对包含文档,查询和相关文件(qrels)的相当经典的Testcollections进行一些评估。 qrels告诉我们lucene应该返回哪些文件与特定查询相关,因此可以测量lucenes搜索质量(使用一些参数,但现在这并不重要)。

我的问题是:测试集合中的文档(即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正确访问Document 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

然而,似乎找不到文档(但它在索引中 - 使用Luke检查)。我总是得到:

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成为一个正常的Field,但也许我在这里完全走错了路?我们非常感谢任何帮助。

提前多多感谢! 扬

1 个答案:

答案 0 :(得分:0)

关于Lucene的内部DocID(即您在ScoreDoc.doc中看到的),您不应将其用作外部ID。它们可以在没有警告的情况下进行更改(尤其是在您更新文档时)。

数字字段(例如IntField)不会作为纯文本编制索引,而是编码为使数字范围搜索高效的表单。要搜索它们,您应该使用NumericRangeQuery,例如:

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

但是,如果这是一个典型的id字段,我就不会使用IntField。大多数时候这样的标识符是为了方便而由数字组成,而不是因为它们代表有意义的数字。通常情况下,如果使用数字范围搜索该字段没有意义,则最好使用StringField代替。