Статьи

Решение проблем с повышением даты и СЕЙЧАС в Solr

Больше зла

В ответ на небольшую проблему, поднятую клиентом, я думал об увеличении даты. Согласно Wiki, хороший способ бост по дате — это что-то вроде следующего:

http://localhost:8983/solr/select?q={!boost b=recip(ms(NOW,manufacturedate_dt),3.16e-11,1,1)}ipod

(см .:   ссылка для повышения даты ). И это работает хорошо, без вопросов.

Тем не менее, при поиске существует небольшая проблема. NOW оценивает текущее время, и каждый последующий запрос будет иметь другое значение для NOW . Этот пост в блоге о влиянии этого на запросы фильтра предоставляет некоторую полезную информацию.

Какое это имеет отношение к повышению даты?

Представьте, что у вас есть несколько страниц результатов. Как правило, каждый строит серию ссылок на страницы, чтобы добраться до последующих страниц, что-то вроде

http://your solr addr/select?q=searchterms&start=10&rows=10

но вам тоже нужно добавить повышение даты, верно? Таким образом, к каждому из этих URL будет добавлено повышение даты сверху (или вы можете указать это в параметрах по умолчанию в solrconfig.xml). И вот где этот фрагмент вызывает некоторое «интересное» поведение ms (NOW, factoryate_dt).
Здесь есть две проблемы.

  1. Вы можете на самом деле повторить или пропустить результаты на странице. Это связано с «ведением» результатов. Несколько секунд могут изменить ускоренные вычисления настолько, что некоторые документы будут пропущены или повторены при просмотре страницы.
  2. Ваш queryResultCache бесполезен.

Краткий обзор queryResultCache

QueryResultCache — это просто карта запроса и некоторое количество документов, по порядку, результаты этого поиска. Сколько документов хранится в кеше, настраивается в solrconfig.xml. Поэтому, как правило, люди будут хранить 2 или 3 страницы результатов на запрос. Этого достаточно для обработки обычного пользовательского опыта; редко пользователи переходят на вторую страницу, а тем более на третью. Когда запрос страницы приходит так, что результатов нет в queryResultCache, запрос выполняется повторно.

Но, что очень важно для этого обсуждения, использование NOW в повышении даты означает, что ни один  запрос, использующий повышение даты, никогда не извлекается из queryResultCache!

Я немного преувеличиваю. С помощью функции повышения даты можно выполнять ограниченную «математику даты», например… ms (NOW / MINUTE, Manufactureate_dt)…. возможны Использование этого techinque уменьшает проблему, но не устраняет ее.

Что может быть сделано?

Я не думал о чистом способе изменить процесс запроса Solr, чтобы справиться с этим. Я могу представить себе новый параметр, такой как «nowIs = 2012-03-28T10: 30: 29Z», с пониманием, что все ссылки на NOW в запросе заменяют его, но это выглядит глупо. Не говоря уже о том, что выполнение этого права затронет множество мест. И я гарантирую, что будет гораздо сложнее понять, чем я думаю …

Другая возможность заключается в том, что вы ограничиваете проблему. Использование некоторого выражения, такого как NOW / DAY + 1DAY, ограничит проблему запросами страниц, которые охватывают полночь. И это повлияет на оценку документов, внесенных в индекс сегодня. Обратите внимание, что если вы попробуете это на необработанном URL-адресе, вам нужно будет избежать экранирования «+» как% 2B.

Третья возможность — использовать тот факт, что Solr счастливо игнорирует параметры URL, которые он не понимает. Вы можете создать собственный QueryComponent и сделать там замены. Это дает вам возможность распознать, что ваш индекс изменился, и повторно выполнить запрос в этом случае. Есть некоторые интересные новые возможности в SearcherLifetimeManager придумывают см в блоге Майка Маккэндлесс здесь ,  которые могли бы помочь , а также, хотя я внимательно не смотрел на нее. Можно было бы просто написать собственный компонент запроса, который распознает «ms (NOW») и подставляет отформатированное время в запрос, но все, что так просто, может иметь неожиданные побочные эффекты.

Другое решение состоит в том, чтобы просто создать ваши URL-адреса подкачки с сырым временем, а не сейчас. Это будет выглядеть так: 

b=recip(ms(2012-03-28T10:40:00Z,manufacturedate_dt),3.16e-11,1,1)}ipod

Самое простое решение — полностью игнорировать проблему. В основном я публикую это как интересное погружение в тонкости с NOW, и о том, как это может произвести эффекты, которые вы не ожидаете. Если вы заинтересованы в том, чтобы выжать из своих экземпляров Solr каждый последний кусочек производительности и сильно увеличиваете по дате, возможно, вы захотите решить эту «проблему».

Но за исключением округления даты (например, используя NOW / DAY + 1DAY вместо простого NOW), я бы никогда не  сделал такого рода вещи, если бы у меня не было абсолютного доказательства, в  котором я нуждался, потому что:

  1. Любое решение, реализующее этот тип процесса, потребует времени и усилий, которые вы могли бы использовать в других частях вашего приложения.
  2. В большинстве приложений ваши пользователи никогда не заметят. Единственный раз, когда это появляется, это когда вы просматриваете страницу, и вы случайно сталкиваетесь с крайним случаем. Пользователи редко переходят даже на вторую страницу результатов поиска, так что это невероятно малая рентабельность инвестиций в процесс кодирования / контроля качества, если и до тех пор, пока в этом нет явной необходимости.