web-dev-qa-db-ja.com

Lucene Indexに保存されているドキュメントを反復処理することは可能ですか?

DocIdフィールドを持つLuceneインデックスにいくつかのドキュメントが保存されています。すべてのdocIdをインデックスに保存したいと思います。問題もあります。ドキュメントの数は約300000なので、このdocIdをサイズ500のチャンクで取得したいと思います。そうすることは可能ですか?

23
Eugeniu Torica
IndexReader reader = // create IndexReader
for (int i=0; i<reader.maxDoc(); i++) {
    if (reader.isDeleted(i))
        continue;

    Document doc = reader.document(i);
    String docId = doc.get("docId");

    // do something with docId here...
}
49
bajafresh4life

Lucene 4

Bits liveDocs = MultiFields.getLiveDocs(reader);
for (int i=0; i<reader.maxDoc(); i++) {
    if (liveDocs != null && !liveDocs.get(i))
        continue;

    Document doc = reader.document(i);
}

詳細については、このページのLUCENE-2600を参照してください。 https://lucene.Apache.org/core/4_0_0/MIGRATE.html

17
bcoughlan

MatchAllDocsQuery という名前のクエリクラスがあります。この場合に使用できると思います。

Query query = new MatchAllDocsQuery();
TopDocs topDocs = getIndexSearcher.search(query, RESULT_LIMIT);
6
Chunliang Lyu

ドキュメント番号(またはID)は、0からIndexReader.maxDoc()-1までの後続の番号になります。これらの番号は永続的ではなく、開いているIndexReaderに対してのみ有効です。 IndexReader.isDeleted(int documentNumber)メソッドを使用してドキュメントが削除されているかどうかを確認できます

2
Yaroslav

上記の例のように.document(i)を使用し、削除されたドキュメントをスキップする場合、結果のページ付けにこのメソッドを使用する場合は注意が必要です。つまり、ページごとに10個のドキュメントリストがあり、ドキュメントを取得する必要があります。 6ページの入力は次のようになります:offset = 60、count = 10(60から70までのドキュメント)。

    IndexReader reader = // create IndexReader
for (int i=offset; i<offset + 10; i++) {
    if (reader.isDeleted(i))
        continue;

    Document doc = reader.document(i);
    String docId = doc.get("docId");
}

Offset = 60から開始するのではなく、offset = 60 + 60より前に表示される削除済みドキュメントの数から開始する必要があるため、削除されたドキュメントでいくつかの問題が発生します。

私が見つけた代替案は次のようなものです:

    is = getIndexSearcher(); //new IndexSearcher(indexReader)
    //get all results without any conditions attached. 
    Term term = new Term([[any mandatory field name]], "*");
    Query query = new WildcardQuery(term);

    topCollector = TopScoreDocCollector.create([[int max hits to get]], true);
    is.search(query, topCollector);

   TopDocs topDocs = topCollector.topDocs(offset, count);

注:[[]]の間のテキストを独自の値に置き換えてください。 150万エントリの大きなインデックスでこれを実行し、1秒未満でランダムに10件の結果を取得しました。同意するのは遅くなりますが、ページ付けが必要な場合は、少なくとも削除されたドキュメントを無視できます。

0
andreyro