Работает ли {Filter} быстрее, чем {Query} в Lucene? - PullRequest
16 голосов
/ 24 июня 2011

Читая «Lucene in Action 2nd edition», я наткнулся на описание Filter классов, которые можно использовать для фильтрации результатов в Lucene. В Lucene есть много фильтров, повторяющих Query классы. Например, NumericRangeQuery и NumericRangeFilter.

В книге говорится, что NRF делает то же самое, что и NRQ, но без оценки документа. Означает ли это, что если мне не нужно оценивать или сортировать документы по значению поля документа , я бы предпочел Filter использовать Query с точки зрения производительности?

Ответы [ 4 ]

12 голосов
/ 28 июня 2011

Я получил отличный ответ от Уве Шиндлера, позвольте мне опубликовать его здесь.

Если вы не кэшируете фильтры, запросы будут выполняться быстрее, как ConjunctionScorer в Lucene есть оптимизации, которые в настоящее время не используются для фильтров. Фильтры хороши, если вы их кешируете (например, если у вас всегда одинаковый доступ ограничения для конкретного пользователя, которые применяются ко всем его запросам). В в этом случае фильтр выполняется только один раз и кешируется для всего запросы, а затем пересекаются с набором результатов запроса.

Если вы хотите только, например, случайным образом «фильтровать», например переменным числовым диапазоном как ограничивающий прямоугольник в географическом поиске, используйте запросы, запросы в большинстве случаи быстрее (например, Range Queries и аналогичные вещи, называемые MultiTermQueries - внутренне также реализованы тем же алгоритмом BitSet, что и Фильтр - на самом деле это всего лишь Фильтры, обернутые в Scorer-impl). Но Оценщик, который ANDs запрос и ваш «фильтр» запрос вместе (ConjunctionScorer), как правило, быстрее, чем код, который применяет фильтр после поиска. Это может улучшить некоторые возможности, но в целом фильтры в Lucene - это то, что больше не нужно, так что уже были некоторые подходы, чтобы сделать фильтры и запросы одинаковыми, и вместо этого тогда можно будет также кэшировать запросы без оценки. Это сделало бы много кода проще.

Фильтры могут принести огромное улучшение скорости с Lucene 4.0, если они подключен поверх IndexReader для фильтрации документов до скоринга, но это еще не реализовано (см. https://issues.apache.org/jira/browse/LUCENE-3212) - Я работаю над этим. Мы может также сделать фильтры произвольным доступом (это легко, поскольку они являются битовыми наборами), что может также улучшить фильтрацию после запроса. Но я бы тогда тоже сделал Запрашивает частично произвольный доступ, если они могут его поддерживать (например, запросы, которые основаны только на FieldCache).

Уве

8 голосов
/ 24 июня 2011

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

A NumericRangeFilter - это просто подкласс MultiTermQueryWrapperFilter, что означает, что по сути он делает что-то вроде этого:

for each document in index:
   if document matches query:
      match[i] = 1
   else
      match[i] = 0

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

Кроме того, фильтр займет больше памяти (один бит для каждого документа в вашем индексе).

Если вы собираетесь использовать тот же запросСнова и снова, тогда, вероятно, стоит заплатить один раз за производительность / память, и последующее использование будет быстрее.Но если это одноразовый запрос, он почти наверняка не стоит.

(Кроме того, если вы собираетесь использовать его повторно, используйте CachingWrapperFilter, чтобы фильтр был кэширован.)

1 голос
/ 07 января 2014

Я нашел это в http://wiki.apache.org/lucene-java/ImproveSearchingSpeed, который, кажется, предлагает использовать фильтры, а не запросы. Интуитивно, для меня это имеет больше смысла, поскольку они должны делать одно и то же, с той лишь разницей, что фильтры не используются в счете.

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

1 голос
/ 24 июня 2011

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

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...