7

私は Lucene 4.2 を使用しており、結果のページネーションを実装しています。

IndexSearcher.searchAfter「次のページ」機能を実装する効率的な方法を提供しますが、「前のページ」または「ページに移動」機能を実装するための最良の方法は何ですか? IndexSearcher.searchBefore例えばありません。

ページサイズを指定してページの総数を決定し、各ページScoreDoc[]の「後」を追跡するために配列を保持することを検討しScoreDocていました(結果がページインされると、配列が設定されます)。これにより、「最も近い」ScoreDocを使用することができますIndexSearcher.searchAfter(最悪の場合は null)。

これは理にかなっていますか?より良いアプローチはありますか?

4

3 に答える 3

14

私は Lucene 4.8 を使用しており、ページネーションを含む REST インターフェイスに取り組んでいます。私の解決策は、TopScoreDocCollector を使用して topDocs(int startIndex, int numberOfhits) メソッドを呼び出すことでした。開始インデックスは、0 から始まるページ番号にヒット数を掛けて計算されます。

...
DirectoryReader reader = DirectoryReader.open(MMapDirectory.open( java.io.File(indexFile) );
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(MAX_RESULTS, true);  // MAX_RESULTS is just an int limiting the total number of hits 
int startIndex = (page -1) * hitsPerPage;  // our page is 1 based - so we need to convert to zero based
Query query = new QueryParser(Version.LUCENE_48, "All", analyzer).parse(searchQuery);
searcher.search(query, collector);
TopDocs hits = collector.topDocs(startIndex, hitsPerPage);
...

したがって、REST インターフェイスは、ページ番号とページあたりのヒット数をパラメーターとして受け入れます。そのため、ページに適切な値を指定して新しいリクエストを送信するだけで、前後に簡単に移動できます

于 2014-07-02T14:11:17.457 に答える
6

Jaimie が説明した解決策に同意します。しかし、検索エンジンの一般的なメカニズムを理解するのに役立つ、知っておくべきもう 1 つの側面を指摘したいと思います。

TopDocCollector を使用すると、結果がスコアまたはその他の並べ替え基準で並べ替えられる前に、検索クエリに一致するヒットをどれだけ収集するかを定義できます。

次の例を参照してください。

collector = TopScoreDocCollector.create(9999, true);
searcher.search(parser.parse("Clone Warrior"), collector);
// get first page
topDocs = collector.topDocs(0, 10);
int resultSize=topDocs.scoreDocs.length; // 10 or less
int totalHits=topDocs.totalHits; // 9999 or less

ここで Lucene に、検索フレーズ「Clone Warrior」を含む最大 9999 個のドキュメントを収集するように指示します。つまり、インデックスにこの検索フレーズを含む 9999 を超えるドキュメントが含まれている場合、コレクターは 9999 ヒットでいっぱいになると停止します。

これは、MAX_RESULTS を選択すると、より良い検索結果になることを意味します。ただし、これは、多数のヒットが予想される場合にのみ関係します。一方、「ルーク スカイウォーカー」を検索してヒットが 1 つしかないと予想される場合は、MAX_RESULTS を 1 に設定することもできます。

そのため、MAX_RESULTS を変更すると、収集されたヒットに対してソートが実行されるため、返される scoreDocs に影響を与える可能性があります。実際には、MAX_RESULTS を十分に大きなサイズに設定して、人間のユーザーが特定のドキュメントを見逃すことを主張できないようにすることです。この概念は、常に完全なデータ プールを考慮する SQL データベースの動作とはまったく逆です。

しかし、lucene は別のメカニズムもサポートしています。コレクターの MAX_RESULTS を定義する代わりに、結果セットを待機する時間を定義することもできます。たとえば、300 ミリ秒後に常にコレクターを停止するように定義できます。これは、パフォーマンスの問題からアプリケーションを保護するための優れたアプローチです。ただし、関連するすべてのドキュメントを確実にカウントしたい場合は、MAX_RESULTS のパラメーターまたは最大待機時間を無制限の値に設定する必要があります。

于 2016-08-26T09:04:34.187 に答える