2015-03-19 2 views
0

Используя Lucene, я делаю некоторую оценку на довольно классических тестовых коллекциях, содержащих документы, запросы и файлы релевантности (qrels). Qrels сообщают нам, какие документы должны быть возвращены lucene как относящиеся к конкретному запросу, поэтому качество поиска lucenes можно измерить (с некоторыми параметрами, но это не важно прямо сейчас).Внешний документ Lucene Id отклоняется от внутреннего индекса docId

Моя проблема заключается в том, что документы в коллекциях тестов (то есть коллекция TIME) имеют свои собственные идентификаторы документов - однако они могут иметь пробелы (например: коллекция TIME содержит 423 документа, но начинается с идентификатора документа 17 и заканчивается с ID 563). Идентификатор документа индексируется и сохраняется как IntField.

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

Однако, я могу (может быть, даже должен) не использовать IndexReader.getTermVectors() метод, чтобы получить доступ к документам их внешних идентификаторы, так как внутренние DocId, используемый Lucene внутри этого метода не соответствуют внешнему идентификатору (из-за пробелов). Я получаю сообщение об ошибке «docID должно быть> = 0 и < maxDoc = 423 (получено docID = 520)».

Каким будет предпочтительный способ заставить lucene правильно обращаться к Документу 520, чтобы вызвать метод getTermVectors для документа через внутренний docId? я пытался получить нужный документ так:

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 нормальное поле, но, может быть, я полностью на ложном пути здесь? Любая помощь будет оценена по достоинству.

Большое спасибо! Jan

ответ

0

Что касается внутреннего DocID Lucene (то есть того, который вы видите в ScoreDoc.doc), вы не должны использовать его как внешний идентификатор. Они могут меняться без предупреждения (особенно если вы когда-либо обновляете документы).

Числовые поля (такие как IntField) не индексируются как обычный текст, а скорее закодированы в форму, которая делает поиск по числовым диапазонам эффективным. Для поиска их, вы должны использовать NumericRangeQuery, такие как:

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

Однако, если это типичное поле идентификатор, я бы не использовать IntField. Большинство идентификаторов времени, подобных этому, состоят из цифр для удобства, а не потому, что они представляют значимые числа. Как правило, если нет смысла искать это поле с числовым диапазоном, вам лучше всего использовать вместо этого StringField.

+0

Спасибо большое - получилось! Я попробовал подход IntField с помощью NumericRangeQuery, и он отлично работает! Я также попробую с StringField позже. – JanJanJan

Смежные вопросы