Количество результатов Elasticsearch изменяется с разбивкой на страницы - PullRequest
1 голос
/ 05 мая 2020

Я использую Elasticsearch 7.6.0 и разбил один из своих запросов на страницы. Кажется, это работает хорошо, и я могу варьировать количество результатов на странице и на выбранной странице, используя параметры поиска from и size.

    query = 'sample query'
    items_per_page = 12
    page = 0

    es_query = {'query': {
        'bool': {
            'must': [{
                'multi_match': {
                    'query': query,
                    "fuzziness": "AUTO",
                    "operator": "and",
                    'fields': ['title^2', 'description']
                },
            }]
        }
    }, 'min_score': 5.0}

    res = es.search(index='my-index', body=es_query, size=items_per_page, from_=items_per_page*page)
    hits = sorted(res['hits']['hits'], key=lambda x: x['_score'], reverse=True)

    print(res['hits']['total']['value']) # This changes depending on the page provided

Я заметил, что количество результатов возвращаемый зависит от предоставленной страницы, что для меня не имеет смысла! Количество результатов тоже колеблется, что меня еще больше смущает: Страница 0, 233 пункта. Страница 1, 157 наименований. Стр. 2, 157 позиций. Страница 3, 233 элемента ...

Почему res['hits']['total']['value'] зависит от размера и от параметров?

Ответы [ 3 ]

1 голос
/ 05 мая 2020

Поиск распределяется и отправляется всем узлам, содержащим шарды, соответствующие искомым индексам. Затем все результаты будут объединены и возвращены. Иногда не все шарды можно найти. Это происходит, когда

  • Кластер очень занят
  • Указанный шард c недоступен из-за процесса восстановления
  • Поиск был оптимизирован и шард был опущен.

В ответе есть раздел _shards, подобный этому:

{
    "took": 1,
    "timed_out": false,
    "_shards":{
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits":{...}
}

Проверьте, есть ли значение, отличное от 0, для сбойных осколков. Если да, проверьте журналы, состояние кластера и индекса.

0 голосов
/ 05 мая 2020

len(res['hits']['hits']) всегда будет возвращать то же число, что указано в items_per_page (т.е. 12 в вашем случае), за исключением последней страницы, где он может возвращать число, меньшее или равное 12.

Однако res['hits']['total']['value'] - это общее количество документов в вашем индексе , а не количество возвращенных результатов. Если количество документов увеличивается, это означает, что новые документы были проиндексированы между последним запросом и текущим.

0 голосов
/ 05 мая 2020

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request -body-search-track-total-hits

Обычно общее количество совпадений не может быть точно рассчитано без посещения всех совпадений, что требует больших затрат для запросов, соответствующих большому количеству документов. Параметр track_total_hits позволяет вам контролировать, как следует отслеживать общее количество обращений. Учитывая, что часто бывает достаточно иметь нижнюю границу количества совпадений, например «есть не менее 10000 совпадений», по умолчанию установлено значение 10,000. Это означает, что запросы будут точно подсчитывать общее попадание до 10 000 попаданий. Это хороший компромисс для ускорения поиска, если вам не нужно точное количество совпадений после определенного порога.

Если установлено значение true, поисковый ответ всегда будет отслеживать количество совпадений, соответствующих запросу точно (например, total.relation всегда будет равняться «eq», когда track_total_hits имеет значение true). В противном случае «total.relation», возвращенный в объекте «total» в ответе на поиск, определяет, как следует интерпретировать «total.value». Значение «gte» означает, что «total.value» - это нижняя граница общего количества совпадений, соответствующих запросу, а значение «eq» указывает, что «total.value» - это точное количество.

...