Câu trả lời xếp hạng cao nhất hiện tại hoạt động, nhưng nó yêu cầu tải toàn bộ danh sách kết quả vào bộ nhớ, có thể gây ra vấn đề bộ nhớ cho tập kết quả lớn và trong mọi trường hợp không cần thiết.
Tôi đã tạo một lớp Java thực hiện một số đẹp Iterator
trên SearchHit
s, cho phép lặp qua tất cả các kết quả. Bên trong, nó xử lý phân trang bằng cách đưa ra các truy vấn bao gồm trường from:
và nó chỉ giữ trong bộ nhớ một trang kết quả.
Cách sử dụng:
// build your query here -- no need for setFrom(int)
SearchRequestBuilder requestBuilder = client.prepareSearch(indexName)
.setTypes(typeName)
.setQuery(QueryBuilders.matchAllQuery())
SearchHitIterator hitIterator = new SearchHitIterator(requestBuilder);
while (hitIterator.hasNext()) {
SearchHit hit = hitIterator.next();
// process your hit
}
Lưu ý rằng, khi tạo bạn SearchRequestBuilder
, bạn không cần phải gọi setFrom(int)
, vì điều này sẽ được thực hiện bởi các interally SearchHitIterator
. Nếu bạn muốn chỉ định kích thước của một trang (nghĩa là số lần truy cập tìm kiếm trên mỗi trang), bạn có thể gọi setSize(int)
, nếu không giá trị mặc định của ElasticSearch được sử dụng.
SearchHitIterator:
import java.util.Iterator;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
public class SearchHitIterator implements Iterator<SearchHit> {
private final SearchRequestBuilder initialRequest;
private int searchHitCounter;
private SearchHit[] currentPageResults;
private int currentResultIndex;
public SearchHitIterator(SearchRequestBuilder initialRequest) {
this.initialRequest = initialRequest;
this.searchHitCounter = 0;
this.currentResultIndex = -1;
}
@Override
public boolean hasNext() {
if (currentPageResults == null || currentResultIndex + 1 >= currentPageResults.length) {
SearchRequestBuilder paginatedRequestBuilder = initialRequest.setFrom(searchHitCounter);
SearchResponse response = paginatedRequestBuilder.execute().actionGet();
currentPageResults = response.getHits().getHits();
if (currentPageResults.length < 1) return false;
currentResultIndex = -1;
}
return true;
}
@Override
public SearchHit next() {
if (!hasNext()) return null;
currentResultIndex++;
searchHitCounter++;
return currentPageResults[currentResultIndex];
}
}
Trong thực tế, thực hiện như thế nào thuận tiện đó là để có một lớp như vậy, tôi tự hỏi tại sao khách hàng Java ElasticSearch của không cung cấp một cái gì đó tương tự.
Tôi cũng gặp vấn đề tương tự. Thans cho câu hỏi của bạn –
Tôi có 100 tài liệu. Tôi đặt Integer.MAX_VALUE là size.Got OutOfMemoryError [Vùng heap Java] cũng có trong My Jboss. Nếu tôi cho 1000, sau đó làm việc tốt. –