簡體   English   中英

如何從 solr 查詢中獲取所有結果?

[英]How to get all results from solr query?

我執行了一些查詢,例如"Address:Jack*" 它顯示numFound = 5214並在結果頁面中顯示 100 個文檔(我將默認顯示結果從 10 更改為 100)。

我怎樣才能得到所有的文件。

我記得自己在做&rows=2147483647

2,147,483,647 是整數的最大值。 我記得曾經使用過一個比那個大的數字並且有一個 NumberFormatException 因為它不能被解析成一個 int。 我不知道他們現在是否使用 Long,但 20 億行通常綽綽有余。

小記:
如果您計划在生產中執行此操作,請小心。 如果您執行類似 *: * 的查詢並且您的索引很大,您可以在該查詢中傳輸幾千兆字節。
如果您知道您不會有很多文檔,請提前 go 並使用整數的最大值。

另一方面,如果您正在執行一次性腳本並且只需要轉儲所有結果(例如文檔 ID),那么這種方法是有效的,如果您不介意等待 3-5 分鍾讓查詢返回。

不要使用 &rows=2147483647

不要使用 Integer.MAX_VALUE(2147483647) 作為生產中行的值。 即使您的結果集很小,這也會大大降低您的查詢速度,因為 solr 會預先分配這個大小的隊列。 參見https://issues.apache.org/jira/browse/SOLR-7580

我強烈建議使用 導出結果集

使用專門設計用於協同處理涉及排序和導出數百萬條記錄的場景的特殊排名查詢解析器和響應編寫器,可以導出完全排序的結果集。

或者我建議使用深度分頁。

當您要閱讀的文檔很少並且您所要做的就是使用startrows參數時,簡單分頁是一件容易的事情。 但是當你有很多文檔時,這不是一個可行的方法,我的意思是數十萬甚至數百萬。
這種情況可能會使您的 Solr 服務器崩潰。

對於向人類用戶顯示搜索結果的典型應用程序,這往往不是什么大問題,因為大多數用戶不關心向下鑽取搜索結果的前幾頁——但對於想要處理有關數據的自動化系統而言匹配一個查詢的所有文檔,這可能會讓人望而卻步。

這意味着如果你有一個網站並且正在分頁搜索結果,那么真實用戶不會 go 走得那么遠,但另一方面要考慮如果蜘蛛或爬蟲試圖閱讀所有網站頁面會發生什么。

現在我們正在談論深度分頁

我建議閱讀這篇精彩的文章:

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

看看這個文檔頁面:

https://solr.apache.org/guide/pagination-of-results.html

這是一個示例,試圖解釋如何使用游標進行分頁。

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;
}

返回所有結果從來都不是一個好的選擇,因為它會降低性能。
你能提一下你的用例嗎?

此外,Solr參數可幫助您調整要返回的結果數。
但是,我認為沒有辦法調整行以返回所有結果。 它不以 -1 作為值。
因此,您需要為所有要返回的結果設置一個高值。

您應該做的是首先創建一個如下所示的 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。

這將幫助您從前一批的最后結果開始執行下一批。

希望這可以幫助。 如果您需要任何說明,請在下方發表評論。

對於通過 Solarium php 客戶端選擇 dismax/edismax 中的所有文檔,正常的查詢語法:不起作用。 對於 select,所有文檔都將 solarium 查詢中的默認查詢值設置為空字符串。 這是必需的,因為 Solarium 中的默認查詢是 還將替代查詢設置為: Dismax/eDismax 普通查詢語法不支持: ,但替代查詢語法支持。

更詳細的可以參考下面的書

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

正如其他答案所指出的那樣,您可以將行配置為最大 integer 以返回查詢的所有結果。 我建議盡管使用Solr 的分頁功能,並構建一個 function,它將使用 cursorMark API 為您返回所有結果。要點是將 cursorMark 參數設置為“*”,設置頁面大小(行參數),並且在每個結果上您將獲得下一頁的 cursorMark,因此您僅使用上一個結果給出的 cursorMark 執行相同的查詢。 通過這種方式,您可以更靈活地以更高效的方式決定要返回多少結果。

我處理問題的方法是運行查詢兩次:

// 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,但會為您提供所有匹配的記錄....性能損失很小。

query.setRows(Integer.MAX_VALUE); 為我工作!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM