Поведение 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.')
Это ^ прекратит нумерацию страниц, как только будет получен полный ответ дубликатов.