Elasticsearch 2.1: Вікно результатів завелике (index.max_result_window)


86

Ми отримуємо інформацію з Elasticsearch 2.1 і дозволяємо користувачеві переглядати результати. Коли користувач запитує великий номер сторінки, ми отримуємо таке повідомлення про помилку:

Вікно результату завелике, розмір від + повинен бути меншим або рівним: [10000], але був [10020]. Див. Api прокрутки для більш ефективного способу запиту великих наборів даних. Цю межу можна встановити, змінивши параметр рівня індексу [index.max_result_window]

Еластичний документ говорить, що це пов’язано з великим споживанням пам'яті та використанням прокручуваного API:

Значення вище, ніж можуть споживати значні шматки пам'яті купи на пошук і на осколок, що виконує пошук. Найбезпечніше залишити це значення, оскільки воно використовується прокручувальним API для будь-якої глибокої прокрутки https://www.elastic.co/guide/en/elasticsearch/reference/2.x/breaking_21_search_changes.html#_from_size_limits

Річ у тім, що я не хочу отримувати великі набори даних. Я хочу лише отримати фрагмент із набору даних, який знаходиться дуже високо в наборі результатів. Також документ, що прокручується, говорить:

Прокрутка не призначена для запитів користувачів у режимі реального часу https://www.elastic.co/guide/en/elasticsearch/reference/2.2/search-request-scroll.html

Це залишає у мене кілька запитань:

1) Чи справді споживання пам'яті було б меншим (будь-який, якщо так, чому), якщо я використовую прокручувальний api для прокрутки вгору до результату 10020 (і ігнорую все нижче 10000) замість того, щоб робити "звичайний" запит пошуку для результату 10000-10020?

2) Не здається, що прокручувальний API - це варіант для мене, але що я повинен збільшити "index.max_result_window". Хтось має якийсь досвід із цим?

3) Чи є інші варіанти вирішення моєї проблеми?

Відповіді:


79

Якщо вам потрібна глибока пагінація, одним із можливих рішень є збільшення значення max_result_window. Це можна curlзробити за допомогою командного рядка оболонки:

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

Я не помітив збільшення використання пам'яті для значень ~ 100k.


У мене та сама помилка. '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.')Там сказано, що вона має 4719 сторінок (результати кожної сторінки 10). і я думаю, що ваша пропозиція працює.
dotslash

1
Це хороше рішення для невеликої кількості документів менше 500000
Еззат,

2
Я використовую ES v2.2.0, і мені довелося змінити корисне навантаження, щоб { "max_result_window" : 500000 }це працювало. Тож команда curl стала -curl -XPUT "http://localhost:9200/my_index/_settings" -d '{ "max_result_window" : 500000 }'
Парін Пореча

3
тим, хто отримує помилку заголовка за допомогою цієї команди для нової версії elasticsearch, вам також потрібно передати заголовок, curl -XPUT " localhost: 9200 / my_index / _settings " -H "Content-Type: application / json" -d '{ "index": {"max_result_window": 50000}} '
Сатіс

32

Правильним рішенням буде використання прокрутки.
Однак, якщо ви хочете збільшити searchвіддачу результатів понад 10000 результатів, ви можете легко це зробити за допомогою Kibana:

Перейдіть Dev Toolsі просто опублікуйте наступне у своєму індексі (your_index_name), вказавши, яким буде нове вікно максимального результату

введіть тут опис зображення

PUT your_index_name/_settings
{ 
  "max_result_window" : 500000 
}

Якщо все піде добре, ви побачите таку відповідь на успіх:

{
  "acknowledged": true
}

1
Я спробував слідувати способу зробити це в коді еластичного пошуку (put_settings тощо) і дійшов до багатьох помилок. Це заощадить мені години! Дякую!
cpres

24

Наступні сторінки в еластичній документації розповідають про глибоке підкачування:

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

Залежно від розміру ваших документів, кількості осколків та апаратного забезпечення, яке ви використовуєте, пошук сторінок із 10 000 до 50 000 результатів (від 1000 до 5000 сторінок) повинен бути цілком здійсненним. Але при достатньо великих значеннях процес сортування дійсно може стати дуже важким, використовуючи величезну кількість процесора, пам’яті та пропускної здатності. З цієї причини ми настійно рекомендуємо забороняти глибоке підкачування.


1
Тож тут, нам слід відмовитися від глибокої пагінації, так? В основному немає сенсу підказувати 4000 сторінок для одного глядача. Скажімо, пошук у Google, навряд чи ми прокручуємо сторінки 8 чи 9, щоб перевірити результати. Зазвичай ми піклуємося лише про 3–5 найкращих сторінок, які нам надає Google.
dotslash

2
Чи можемо ми використовувати API прокрутки у випадку, якщо нам потрібна глибока пагінація?
Abhi.G

3
Але коли ми вмикаємо функцію сортування, скажімо, на сайті електронної комерції. коли користувач хоче бачити товари з найвищою ціною. Результат буде іншим, коли ми сортуємо за найвищою ціною порівняно з тим, коли ми сортуємо за найнижчою сторінкою, але переходимо до останньої сторінки, чи не так? оскільки ми обмежуємо кількість результатів, до яких можна отримати доступ. будь-яка робота навколо цього?
MR Murazza

3

Використовуйте API прокрутки, щоб отримати більше 10000 результатів.

Приклад прокрутки в ElasticSearch NEST API

Я використовував це так:

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

Якщо ви хочете отримати більше 10000 результатів, тоді у всіх вузлах даних використання пам’яті буде дуже великим, оскільки воно має повертати більше результатів у кожному запиті запиту. Тоді, якщо у вас більше даних і більше осколків, то об’єднання цих результатів буде неефективним. Також кеш контекст фільтра, отже, знову більше пам'яті. Вам потрібно пробувати і помиляти, скільки саме ви приймаєте. Якщо ви отримуєте багато запитів у маленькому вікні, вам слід зробити кілька запитів на більше 10 тис. І об'єднати його самостійно в коді, який повинен зайняти менше пам'яті програми, ніж при збільшенні розміру вікна.


0

2) Не здається, що прокручувальний API - це варіант для мене, але що я повинен збільшити "index.max_result_window". Хтось має якийсь досвід із цим?

-> Ви можете визначити це значення в шаблонах індексів, шаблон es застосовуватиметься лише для нових індексів, тому вам доведеться або видалити старі індекси після створення шаблону, або дочекатися введення нових даних у еластичному пошуку.

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


0

У моєму випадку здається, що зменшення результатів за допомогою префіксів від & size до запиту видалить помилку, оскільки нам не потрібні всі результати:

GET widgets_development/_search
{
  "from" : 0, 
  "size": 5,
  "query": {
    "bool": {}
  },
  "sort": {
    "col_one": "asc"
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.