Фильтрация по диапазону дат в Lucene

Я знаю, что заголовок может указывать на то, что это дубликат, но я не смог найти ответ на этот конкретный вопрос:

Мне нужно отфильтровать результаты поиска по диапазону дат. Дата каждого документа хранится (но не индексируется) на каждом из них. При использовании фильтра я заметил, что фильтр вызывается со всеми документами в индексе.

Это означает, что фильтр будет работать медленнее по мере роста индекса (в настоящее время в нем всего около 300 000 документов), поскольку ему приходится перебирать каждый отдельный документ.

Я не могу использовать RangeQuery, так как дата не индексируется.

Как я могу применить фильтр ПОСЛЕ только к документам, которые являются результатами запроса, чтобы сделать его более эффективным?

Я предпочитаю делать это до того, как мне вручат результаты, чтобы не испортить имеющиеся у меня баллы и сборщиков.


person Khash    schedule 15.07.2010    source источник


Ответы (2)


Не совсем уверен, поможет ли это, но у меня была проблема, похожая на вашу, и я придумал следующее (+ примечания):

  1. Я думаю, вам действительно придется индексировать поле даты. Ничто другое не имеет смысла с точки зрения запросов/фильтрации и т. д.
  2. В Lucene.net v2.9 запросы диапазона, где много терминов, кажется, стали ужасно медленными по сравнению с v2.9.
  3. Я исправил свои проблемы со скоростью при использовании полей даты, переключившись на использование числового поля и запросов числового поля. Это на самом деле дало мне значительный прирост скорости по сравнению с моей базовой версией Lucene.net v2.4.
  4. Помещение вашего запроса в фильтр-оболочку кэширования означает, что вы можете использовать набор битов документа для фильтра. Это также значительно ускорит последующие запросы с использованием того же фильтра.
  5. Фильтр не влияет на оценку набора результатов запроса.
  6. Присоединение вашего кэшированного фильтра к остальной части вашего запроса (где, я думаю, у вас есть свои собственные оценки и коллекторы) означает, что он должен соответствовать последней части ваших критериев.

Итак, подведем итог: индексируйте поля даты как числовые поля; создавайте свои запросы как запросы числового диапазона; преобразовать их в кешированные оболочки фильтра и повесить на них.

Я думаю, вы увидите впечатляющее ускорение по сравнению с текущим использованием индекса.

Удачи!

p.s. Я бы никогда не угадал, что будет быстрым или медленным при использовании Lucene. Я всегда был удивлен в обоих направлениях!

person Adrian Conlon    schedule 17.07.2010

Во-первых, чтобы фильтровать поле, оно должно быть проиндексировано.

Во-вторых, использование фильтра считается лучшим способом ограничить набор документов для поиска. Одна из причин этого заключается в том, что вы можете кэшировать результаты фильтрации для использования в других запросах. И структура данных фильтра довольно эффективна: это битовый набор документов, соответствующих фильтру.

Но если вы настаиваете на том, чтобы не использовать фильтры, я думаю, что единственный способ — использовать логический запрос для фильтрации.

person Pascal Dimassimo    schedule 16.07.2010
comment
Установлен ли бит для документов, соответствующих фильтру (что означает, что вы должны предоставить все документы) или установлен бит для условий, соответствующих фильтру? Я предполагаю, что кеширование было бы возможно, если бы оно было на Условиях. - person Khash; 16.07.2010
comment
Это битовый набор документов, соответствующих фильтру. Это позволяет искать в том же подмножестве документов другой запрос при использовании того же фильтра. - person Pascal Dimassimo; 16.07.2010
comment
Паскаль, существуют ли какие-либо стратегии для поддержания этого фильтра BitSet в актуальном состоянии при условии, что документы изменяются, добавляются новые документы, а некоторые удаляются? - person jottos; 27.11.2010