Поведение totalEstimatedMatches с Microsoft (Bing) Cognitive Search API (v5)

Недавно конвертировал некоторый код Bing Search API v2 в v5, и он работает, но мне любопытно поведение "totalEstimatedMatches". Вот пример, чтобы проиллюстрировать мой вопрос:

Пользователь на нашем сайте ищет определенное слово. Запрос API возвращает 10 результатов (наша настройка размера страницы), а totalEstimatedMatches установлен на 21. Поэтому мы указываем 3 страницы результатов и пропускаем страницу пользователя.

Когда они попадают на страницу 3, totalEstimatedMatches возвращает 22, а не 21. Кажется странным, что при таком маленьком наборе результатов он уже не должен знать, что это 22, но хорошо, я могу с этим смириться. Все результаты отображаются правильно.

Теперь, если пользователь снова возвращается со страницы 3 на страницу 2, значение totalEstimatedMatches снова равно 21. Это удивляет меня, потому что, как только набор результатов пройден, API, вероятно, должен знать, что есть 22, а не 21 результат.

Я был профессиональным разработчиком программного обеспечения с 80-х годов, поэтому я понял, что это одна из тех чертовых проблем, связанных с дизайном API. Очевидно, это не кеширование точного количества результатов или чего-то еще. Я просто не помню такого поведения в API поиска V2 (который, как я понимаю, был сторонним кодом). Это было довольно надежно по количеству результатов.

Удивляет ли это кого-нибудь, кроме меня, как-то неожиданно?

1 ответ

Решение

Оказывается, это причина, по которой поле JSON ответа totalEstimatedMatches включает в себя слово ...Estimated... и не просто называется totalMatches:

"... индекс поисковой системы не поддерживает точную оценку общего соответствия".

Взято из: Результаты поиска по страницам API поиска новостей V5 со смещением и количеством

Как и следовало ожидать, чем меньше результатов вы получите, тем больше ошибка% вы увидите в totalEstimatedMatches значение. Аналогично, чем сложнее ваш запрос (например, выполнение составного запроса, такого как ../search?q=(foo OR bar OR foobar)&...что на самом деле 3 поиска, упакованные в 1), тем больше вариаций это значение проявляется.

Тем не менее, мне удалось (по крайней мере, предварительно) компенсировать это, установив offset == totalEstimatedMatches и создание простой функции проверки эквивалентности.

Вот тривиальный пример в Python:

while True:
    if original_totalEstimatedMatches < new_totalEstimatedMatches:
       original_totalEstimatedMatches = new_totalEstimatedMatches.copy()

       #set_new_offset_and_call_api() is a func that does what it says.
       new_totalEstimatedMatches = set_new_offset_and_call_api()
    else:
        break

Пересматривая API, и я нашел способ эффективно разбивать страницы на страницы без использования "totalEstimatedMatches" возвращаемое значение:

class ApiWorker(object):
    def __init__(self, q):
        self.q = q
        self.offset = 0
        self.result_hashes = set()
        self.finished = False

    def calc_next_offset(self, resp_urls):
       before_adding = len(self.result_hashes)
       self.result_hashes.update((hash(i) for i in resp_urls)) #<==abuse of set operations.
       after_adding = len(self.result_hashes)
       if after_adding == before_adding: #<==then we either got a bunch of duplicates or we're getting very few results back.
           self.complete = True
       else:
           self.offset += len(new_results)

    def page_through_results(self, *args, **kwargs):
        while not self.finished:
            new_resp_urls = ...<call_logic>...
            self.calc_next_offset(new_resp_urls)
            ...<save logic>...
        print(f'All unique results for q={self.q} have been obtained.')

Это ^ прекратит нумерацию страниц, как только будет получен полный ответ дубликатов.

Другие вопросы по тегам