Elasticsearch 2.1: Cửa sổ kết quả quá lớn (index.max_result_window)


86

Chúng tôi lấy thông tin từ Elasticsearch 2.1 và cho phép người dùng duyệt trang thông qua kết quả. Khi người dùng yêu cầu số trang cao, chúng tôi nhận được thông báo lỗi sau:

Cửa sổ kết quả quá lớn, từ + kích thước phải nhỏ hơn hoặc bằng: [10000] nhưng là [10020]. Xem api cuộn để biết cách hiệu quả hơn để yêu cầu tập dữ liệu lớn. Có thể đặt giới hạn này bằng cách thay đổi thông số cấp chỉ mục [index.max_result_window]

Tài liệu đàn hồi nói rằng điều này là do tiêu thụ bộ nhớ cao và để sử dụng api cuộn:

Các giá trị cao hơn có thể tiêu tốn một lượng lớn bộ nhớ heap trên mỗi lần tìm kiếm và mỗi phân đoạn thực hiện tìm kiếm. An toàn nhất là để lại giá trị này vì đây là cách sử dụng api cuộn cho bất kỳ cuộn sâu nào https://www.elastic.co/guide/en/elasticsearch/reference/2.x/break_21_search_changes.html#_from_size_limits

Vấn đề là tôi không muốn truy xuất các tập dữ liệu lớn. Tôi chỉ muốn truy xuất một lát từ tập dữ liệu nằm rất cao trong tập kết quả. Ngoài ra, tài liệu cuộn cho biết:

Thao tác cuộn không dành cho yêu cầu của người dùng trong thời gian thực https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

Điều này khiến tôi có một số câu hỏi:

1) Mức tiêu thụ bộ nhớ có thực sự thấp hơn (bất kỳ nếu vậy tại sao) nếu tôi sử dụng api cuộn để cuộn đến kết quả 10020 (và bỏ qua mọi thứ dưới 10000) thay vì thực hiện yêu cầu tìm kiếm "bình thường" cho kết quả 10000-10020 không?

2) Có vẻ như API cuộn không phải là một tùy chọn đối với tôi mà là tôi phải tăng "index.max_result_window". Có ai có bất cứ kinh nghiệm với điều này?

3) Có bất kỳ tùy chọn nào khác để giải quyết vấn đề của tôi không?

Câu trả lời:


79

Nếu bạn cần phân trang sâu, một giải pháp khả thi là tăng giá trị max_result_window. Bạn có thể sử dụng curlđể thực hiện việc này từ dòng lệnh shell của mình:

curl -XPUT "http://localhost:9200/my_index/_settings" -H 'Content-Type: application/json' -d '{ "index" : { "max_result_window" : 500000 } }'

Tôi không nhận thấy việc sử dụng bộ nhớ tăng lên, đối với các giá trị ~ 100k.


Tôi bị lỗi tương tự 'Result window is too large, from + size must be less than or equal to: [10000] but was [47190]. See the scroll api for a more efficient way to request large data sets. This limit can be set by changing the [index.max_result_window] index level parameter.')Nó cho biết nó có 4719 trang (mỗi trang 10 kết quả). và tôi nghĩ rằng đề xuất của bạn hiệu quả.
dotlash

1
Đây là một giải pháp tốt cho số lượng nhỏ các tài liệu ít hơn 500000
Ezzat

2
Tôi đang sử dụng ES v2.2.0 và tôi đã phải thay đổi tải trọng để { "max_result_window" : 500000 }điều này hoạt động. Vì vậy, lệnh curl đã trở thành -curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Parin Porecha

3
đối với những người gặp lỗi tiêu đề với lệnh này cho phiên bản mới hơn củaasticsearch, bạn cũng cần phải chuyển tiêu đề, curl -XPUT " localhost: 9200 / my_index / _settings " -H "Content-Type: application / json" -d '{ "index": {"max_result_window": 50000}} '
bảy,

32

Giải pháp phù hợp sẽ là sử dụng tính năng cuộn.
Tuy nhiên, nếu bạn muốn mở rộng kết quả searchtrả về vượt quá 10.000 kết quả, bạn có thể thực hiện dễ dàng với Kibana:

Dev ToolsTruy cập và chỉ đăng phần sau lên chỉ mục của bạn (your_index_name), xác định đâu sẽ là cửa sổ kết quả tối đa mới

nhập mô tả hình ảnh ở đây

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

Nếu mọi việc suôn sẻ, bạn sẽ thấy phản hồi thành công sau:

{
  "acknowledged": true
}

1
Tôi đã thử làm theo cách thực hiện việc này trong mã đàn hồi tìm kiếm (put_settings, v.v.) và gặp nhiều lỗi. Điều này giúp tôi tiết kiệm hàng giờ! Cảm ơn bạn!
cpres

24

Các trang sau trong tài liệu đàn hồi nói về phân trang sâu:

https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html https://www.elastic.co/guide/en/elasticsearch/guide/current/_fetch_phase.html

Tùy thuộc vào kích thước tài liệu của bạn, số lượng phân đoạn và phần cứng bạn đang sử dụng, việc phân trang sâu 10.000 đến 50.000 kết quả (1.000 đến 5.000 trang) hoàn toàn có thể thực hiện được. Nhưng với các giá trị đủ lớn, quá trình sắp xếp thực sự có thể trở nên rất nặng nề, sử dụng một lượng lớn CPU, bộ nhớ và băng thông. Vì lý do này, chúng tôi đặc biệt khuyên bạn không nên phân trang sâu.


1
Vì vậy, ở đây, chúng ta nên bỏ phân trang sâu sắc, phải không? Về cơ bản, không có ý nghĩa của việc phân trang 4000 trang cho một người xem. Giả sử, tìm kiếm trên google, hầu như chúng ta không cuộn đến trang 8 hoặc 9 để kiểm tra kết quả. Thông thường chúng ta chỉ quan tâm đến 3-5 trang hàng đầu mà Google cung cấp cho chúng ta.
dotlash

2
Chúng tôi có thể sử dụng API cuộn trong trường hợp chúng tôi cần phân trang sâu không?
Abhi.G

3
Nhưng khi chúng tôi bật tính năng sắp xếp, hãy nói trên một trang Thương mại điện tử. khi người dùng muốn xem các mặt hàng có giá cao nhất. Kết quả sẽ khác khi chúng ta sắp xếp theo giá cao nhất so với khi chúng ta sắp xếp theo trang thấp nhất nhưng chuyển đến trang cuối cùng phải không? vì chúng tôi giới hạn số lượng kết quả có thể được truy cập. bất kỳ công việc xung quanh cho điều này?
MR Murazza

3

Sử dụng API cuộn để nhận được hơn 10000 kết quả.

Ví dụ về cuộn trong API NEST ElasticSearch

Tôi đã sử dụng nó như thế này:

private static Customer[] GetCustomers(IElasticClient elasticClient)
{
    var customers = new List<Customer>();
    var searchResult = elasticClient.Search<Customer>(s => s.Index(IndexAlias.ForCustomers())
                          .Size(10000).SearchType(SearchType.Scan).Scroll("1m"));

    do
    {
        var result = searchResult;
        searchResult = elasticClient.Scroll<Customer>("1m", result.ScrollId);
        customers.AddRange(searchResult.Documents);
    } while (searchResult.IsValid && searchResult.Documents.Any());

    return customers.ToArray();
}

0

Nếu bạn muốn nhiều hơn 10000 kết quả thì trong tất cả các nút dữ liệu, việc sử dụng bộ nhớ sẽ rất cao vì nó phải trả về nhiều kết quả hơn trong mỗi yêu cầu truy vấn. Sau đó, nếu bạn có nhiều dữ liệu hơn và nhiều phân đoạn hơn thì việc hợp nhất các kết quả đó sẽ không hiệu quả. Cũng es cache bối cảnh bộ lọc, do đó một lần nữa bộ nhớ nhiều hơn. Bạn phải thử và sai số lượng chính xác bạn đang dùng. Nếu bạn nhận được nhiều yêu cầu trong cửa sổ nhỏ, bạn nên thực hiện nhiều truy vấn với số tiền hơn 10k và tự hợp nhất nó trong mã, điều này được cho là sẽ chiếm ít bộ nhớ ứng dụng hơn nếu bạn tăng kích thước cửa sổ.


0

2) Có vẻ như API cuộn không phải là một tùy chọn đối với tôi mà là tôi phải tăng "index.max_result_window". Có ai có bất cứ kinh nghiệm với điều này?

-> Bạn có thể xác định giá trị này trong các mẫu chỉ mục, mẫu es sẽ chỉ áp dụng cho các chỉ mục mới, vì vậy bạn phải xóa các chỉ mục cũ sau khi tạo mẫu hoặc đợi dữ liệu mới được nhập vào trong đàn hồi tìm kiếm.

{"order": 1, "template": "index_template *", "settings": {"index.number_of_replicas": "0", "index.number_of_shards": "1", "index.max_result_window": 2147483647},


0

Trong trường hợp của tôi, có vẻ như việc giảm kết quả thông qua tiền tố from & size cho truy vấn sẽ loại bỏ lỗi vì chúng tôi không cần tất cả kết quả:

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.