Миграция с Hit/Hits на TopDocs/TopDocCollector

У меня есть код, похожий на:

final Term t = /* ... */;
final Iterator i = searcher.search( new TermQuery( t ) ).iterator();
while ( i.hasNext() ) {
    Hit hit = (Hit)i.next();
    // "FILE" is the field that recorded the original file indexed
    File f = new File( hit.get( "FILE" ) );
    // ...
}

Мне непонятно, как переписать код с помощью TopDocs/TopDocCollector и как выполнить итерацию по всем результатам.

Ответы

Ответ 1

В принципе, вам нужно определить предел количества ожидаемых результатов. Затем вы перебираете все ScoreDoc в результате TopDocs.

final MAX_RESULTS = 10000;
final Term t = /* ... */;
final TopDocs topDocs = searcher.search( new TermQuery( t ), MAX_RESULTS );
for ( ScoreDoc scoreDoc : topDocs.scoreDocs ) {
    Document doc = searcher.doc( scoreDoc.doc )
    // "FILE" is the field that recorded the original file indexed
    File f = new File( doc.get( "FILE" ) );
    // ...
}

Это в основном то, что делает класс Hits, только он устанавливает предел в результатах 50, и если вы повторяете это, то поиск повторяется, что обычно является расточительным. Вот почему он устарел.

ADDED. Если нет предела, вы можете указать количество результатов, вы должны использовать HitCollector:

final Term t = /* ... */;
final ArrayList<Integer> docs = new ArrayList<Integer>();
searcher.search( new TermQuery( t ), new HitCollector() {
    public void collect(int doc, float score) {
        docs.add(doc);
    }
});

for(Integer docid : docs) {
    Document doc = searcher.doc(docid);
    // "FILE" is the field that recorded the original file indexed
    File f = new File( doc.get( "FILE" ) );
    // ...
}