Является ли {Фильтр} быстрее, чем {Запрос в Lucene?
При чтении "Lucene in Action 2nd edition" я столкнулся с описанием классов Filter
, которые могут быть использованы для фильтрации результатов в Lucene. У Lucene много фильтров, повторяющих классы Query
. Например, NumericRangeQuery
и NumericRangeFilter
.
В книге говорится, что NRF
делает то же самое, что и NRQ
, но без скоринга документа. Означает ли это, что, если мне не нужны скоринг или сортировка документов по значению поля документа, я должен предпочесть Filter
ing over Query
ing с точки зрения производительности?
Ответы
Ответ 1
Я получаю отличный ответ от Уве Шиндлера, позвольте мне перепечатать его здесь.
Если вы не кэшируете фильтры, запросы будут быстрее, так как ConjunctionScorer в Lucene есть оптимизации, которые в настоящее время не используются для фильтров. Фильтры в порядке, если вы их кешируете (например, если у вас всегда есть тот же доступ ограничения для конкретного пользователя, которые применяются ко всем его запросам). В в этом случае фильтр выполняется только один раз и кэшируется для дальнейшего запросов, а затем пересекается с набором результатов запроса.
Если вы хотите только, например, случайным образом "фильтровать", например. переменным числовым диапазоном как ограничивающий прямоугольник в географическом поиске, использовать запросы, запросы в большинстве (например, запросы диапазона и аналогичные материалы - MultiTermQueries - внутренне реализованы также одним и тем же алгоритмом BitSet, как и Фильтр - на самом деле это только фильтры, обернутые Scorer-impl). Но Счетчик, который ИД запроса и ваш запрос "фильтр" вместе (ConjunctionScorer) обычно быстрее, чем код, который применяет фильтр после поиска. Это может привести к некоторому улучшению, но в целом фильтры - это что-то в Люцене, что больше не нужно, так что были уже некоторые подходы к тому, чтобы сделать фильтры и запросы одинаковыми, и вместо этого они могут также кэшировать незарегистрированные запросы. Это сделало бы лоты кода проще.
Фильтры могут значительно увеличить скорость работы с Lucene 4.0, если они подключен к ontop IndexReader для фильтрации документов до подсчета очков, но это еще не реализовано (см. https://issues.apache.org/jira/browse/LUCENE-3212) - Я работаю над этим. Мы также могут делать произвольный доступ к фильтрам (это легко, поскольку они являются битами), что может также улучшить фильтрацию после запроса. Но тогда я также Запросы частично произвольного доступа, если они могут его поддерживать (например, запросы, которые основаны только на FieldCache).
Уве
Ответ 2
В отличие от ответа Денниса: нет, вы, вероятно, не хотите использовать фильтр, если не собираетесь повторно использовать один и тот же запрос несколько раз.
A NumericRangeFilter
является всего лишь подклассом MultiTermQueryWrapperFilter
, что означает, что по существу он делает что-то вроде этого:
for each document in index:
if document matches query:
match[i] = 1
else
match[i] = 0
Таким образом, он будет работать в линейном времени по вашему индексу вместо логарифмического времени, как обычный запрос.
Кроме того, фильтр будет занимать больше памяти (один бит для каждого документа в вашем индексе).
Если вы собираетесь использовать один и тот же запрос снова и снова, то, вероятно, стоит вам заплатить за производительность/память сразу, а позже - быстрее. Но если это одноразовый запрос, это почти наверняка не стоит.
(Кроме того, если вы собираетесь его повторно использовать, используйте CachingWrapperFilter
, чтобы фильтр был кеширован.)
Ответ 3
Если фильтр будет повторно использован, целесообразно использовать это вместо запросов из-за целей кеширования. Если вы не собираетесь использовать значения скоринга или поля, также имеет смысл использовать фильтр по запросу.
Надеюсь, это поможет.
Ответ 4
Я нашел это в http://wiki.apache.org/lucene-java/ImproveSearchingSpeed, который, кажется, предлагает использовать фильтры, а не запросы. Интуитивно это имеет смысл для меня, поскольку они в значительной степени должны делать то же самое, с той лишь разницей, что фильтры не используются в баллах.
Рассмотрим использование фильтров. Это может быть намного эффективнее ограничить приводит к тому, что часть индекса использует кеш-бит чем использование предложения запроса. Это особенно верно для ограничений которые соответствуют большому количеству документов большого индекса. Фильтры обычно используется для ограничения результатов в категории, но во многих случаях случаи используются для замены любого предложения запроса. Одно отличие между использование запроса и фильтра - это то, что запрос влияет на пока нет фильтра.