web-dev-qa-db-ja.com

solrクエリからすべての結果を取得する方法は?

"Address:Jack*"のようなクエリを実行しました。 numFound = 5214を表示し、結果ページに100個のドキュメントを表示します(デフォルトの表示結果を10から100に変更しました)。

すべてのドキュメントを取得するにはどうすればよいですか。

24

自分が&rows = 2147483647を実行したことを覚えています

2,147,483,647は整数の最大値です。私はそれよりも大きい数を一度使用し、それをintに解析できなかったためにNumberFormatExceptionを持っていたことを思い出します。現在、Longを使用しているかどうかはわかりませんが、通常は20億行で十分です。

小さなメモ:
本番環境でこれを行う場合は注意してください。 *:*のようなクエリを実行し、インデックスが大きい場合、そのクエリで数ギガバイトを転送できます。
ドキュメントの数が少ないことがわかっている場合は、整数の最大値を使用してください。

一方、1回限りのスクリプトを実行していて、すべての結果(ドキュメントIDなど)をダンプする必要がある場合は、返すクエリ。

35
Fermin Silva

すべての結果を返すことは、パフォーマンスが非常に遅くなるため、決して良い選択肢ではありません。
ユースケースについて教えてください。

また、Solr rows パラメーターは、返される結果の数を調整するのに役立ちます。
ただし、すべての結果を返すように行を調整する方法はないと思います。値として-1を取りません。
したがって、返されるすべての結果に対して高い値を設定する必要があります。

7
Jayendra

ディープページングを使用することをお勧めします。

シンプルなページネーションは、読み取るドキュメントがほとんどなく、startパラメーターとrowsパラメーターを操作するだけで済む場合に簡単です。しかし、あなたが多くの文書を持っている場合、私は数十万、さらには数百万を意味しますが、これは実行可能な方法ではありません。
これは、Solrサーバーをひざまずかせる可能性のあるものです。

検索結果を人間のユーザーに表示する典型的なアプリケーションの場合、ほとんどのユーザーは検索結果の最初の数ページをドリルダウンすることを気にしないので、これは大きな問題にはなりません。クエリに一致するすべてのドキュメントは、非常に禁止的です。

つまり、Webサイトがあり、検索結果をページングしている場合、実際のユーザーはそれ以上先に進むことはありませんが、スパイダーまたはスクレーパーがすべてのWebサイトページを読み込もうとするとどうなるかを考えます。

現在、ディープページングについて説明しています。

この素晴らしい投稿を読むことをお勧めします。

https://lucidworks.com/blog/2013/12/12/coming-soon-to-solr-efficient-cursor-based-iteration-of-large-result-sets/

そして、このドキュメントページをご覧ください。

https://cwiki.Apache.org/confluence/display/solr/Pagination+of+Results

そして、カーソルを使用してページ分割する方法を説明しようとする例があります。

SolrQuery solrQuery = new SolrQuery();
solrQuery.setRows(500);
solrQuery.setQuery("*:*");
solrQuery.addSort("id", ORDER.asc);  // Pay attention to this line
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
while (!done) {
    solrQuery.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
    QueryResponse rsp = solrClient.query(solrQuery);
    String nextCursorMark = rsp.getNextCursorMark();
    for (SolrDocument d : rsp.getResults()) {
            ... 
    }
    if (cursorMark.equals(nextCursorMark)) {
        done = true;
    }
    cursorMark = nextCursorMark;
}
3
freedev

まず、以下に示すSolrQueryを作成し、バッチで取得するドキュメントの数を設定します。

int lastResult=0; //this is for processing the future batch

String query = "id:[ lastResult TO *]"; // just considering id for the sake of simplicity

SolrQuery solrQuery = new SolrQuery(query).setRows(500); //setRows will set the required batch, you can change this to whatever size you want.

SolrDocumentList results = solrClient.query(solrQuery).getResults(); //execute this statement

ここでは、IDによる検索の例を検討しています。検索するパラメーターに置き換えることができます。

「lastResult」は、最初の500レコード(500はバッチサイズ)の実行後に変更でき、結果から取得した最後のIDに設定できる変数です。

これは、前のバッチの最後の結果から開始して、次のバッチを実行するのに役立ちます。

お役に立てれば。明確化が必要な場合は、以下のコメントを作成してください。

2
Apurv Nerlekar

他の回答が指摘したように、クエリのすべての結果を返すために、行を最大整数に設定できます。 ページネーションのSolr機能 を使用し、cursorMark APIを使用してすべての結果を返す関数を作成することをお勧めします。その要点は、cursorMarkパラメーターを「*」に設定し、ページサイズ(rowsパラメーター)を設定し、各結果で次のページのcursorMarkを取得することです。したがって、同じクエリをcursorMarkでのみ実行します。最後の結果から与えられます。これにより、結果をどれだけ戻すかについて、よりパフォーマンスの高い方法でより柔軟になります。

0
itayad

Solarium phpクライアントを介してdismax/edismaxのすべてのドキュメントを選択する場合、通常のクエリ構文は機能しません。すべてのドキュメントを選択するには、solaliumクエリのデフォルトのクエリ値を空の文字列に設定します。 Solariumのデフォルトクエリはであるため、これが必要です。また、代替クエリをに設定します。 Dismax/eDismaxの通常のクエリ構文はをサポートしませんが、代替クエリ構文はサポートします。

詳細については、次の本を参照できます

http://www.packtpub.com/Apache-solr-php-integration/book

0
jayant

私が問題に対処した方法は、クエリを2回実行することです。

// Start with your (usually small) default page size
solrQuery.setRows(50); 
QueryResponse response = solrResponse(query);
if (response.getResults().getNumFound() > 50) {
    solrQuery.setRows(response.getResults().getNumFound()); 
    response = solrResponse(query);
}

Solrを2回呼び出しますが、一致するすべてのレコードを取得します。パフォーマンスがわずかに低下します。

0
Ya.Ma