Запросы против фильтров


198

Я не вижу описания того, когда мне следует использовать запрос, фильтр или какую-то их комбинацию. В чем разница между ними? Кто-нибудь может объяснить, пожалуйста?


46
Официальная документация на самом деле не очень понятна
geekazoid

2
Похоже, там появилась страница с более подробным объяснением : astic.co/guide/en/elasticsearch/guide/master/…
Дмитрий Полушкин

6
Стоит отметить, что запросы и фильтры будут объединены в ES 2.0, поэтому большая часть сказанного и написанного для запросов и фильтров больше не будет применяться. Также проверьте официальное сообщение в блоге, объявляющее об этом изменении.
Val

Ответы:


201

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


19
Хорошо, если пользователь выполняет поиск по типу Google, я бы использовал запрос? Если они выбирают возможное значение из выпадающего списка (например, счет-фактура> 50), тогда это будет фильтр?
Джонси

4
Да, это совершенно верно. В любое время, когда вам нужно ограничить весь набор документов каким-либо показателем, обычно бывает так, что фильтр подходит. Так что, может быть, по возрасту, длине, размеру и т. Д.
Зак

Мое решение использует фильтры и запросы в одном запросе, и оно очень быстрое в тестовой базе данных. Мы скоро получим данные в реальном времени, чтобы увидеть, насколько быстро это происходит.
Jonesie

@ Zach Чтобы быть абсолютно ясным, в мультитенантной системе - с разрешениями для пользователей внутри арендатора - похоже, что информация об арендаторе / аутентификации будет фильтром, добавляемым к каждому запросу (то есть фильтрованным запросом). Правильно?
Скотт Виллек

4
@activescott Да, я бы так и сделал. Вы также можете настроить отфильтрованные псевдонимы, чтобы «пользовательские псевдонимы» всегда применяли соответствующий фильтр. Упрощает администрирование и не требует изменений в коде для обновления запросов, дополнительных затрат в вашем запросе и т. Д.
Зак

99

Вот что говорится в официальной документации:

Как правило, вместо запросов следует использовать фильтры:

  • для бинарных поисков да / нет
  • для запросов на точные значения

Как правило, вместо фильтров следует использовать запросы:

  • для полнотекстового поиска
  • где результат зависит от оценки релевантности

когда я хочу удалить документ, должен ли я использовать фильтр, если это возможно? Я не хочу, чтобы это кешировалось
Rytek

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

13

Пример (попробуйте сами)

Индекс Say myindexсодержит три документа:

curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hello world!" }'
curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hello world! I am Sam." }'
curl -XPOST localhost:9200/myindex/mytype  -d '{ "msg": "Hi Stack Overflow!" }'

Запрос: насколько документ соответствует запросу

Запрос hello sam(используя ключевое слово must)

curl localhost:9200/myindex/_search?pretty  -d '
{
  "query": { "bool": { "must": { "match": { "msg": "hello sam" }}}}
}'

Документу "Hello world! I am Sam."присваивается более высокий балл, чем "Hello world!", поскольку первый соответствует обоим словам в запросе. Документы оцениваются.

"hits" : [
   ...
     "_score" : 0.74487394,
     "_source" : {
       "name" : "Hello world! I am Sam."
     }
   ...
     "_score" : 0.22108285,
     "_source" : {
       "name" : "Hello world!"
     }
   ...

Фильтр: соответствует ли документ запросу

Фильтр hello sam(используя ключевое слово filter)

curl localhost:9200/myindex/_search?pretty  -d '
{
  "query": { "bool": { "filter": { "match": { "msg": "hello sam" }}}}
}'

Документы, которые содержат helloили samвозвращены. Документы НЕ оцениваются .

"hits" : [
   ...
     "_score" : 0.0,
     "_source" : {
       "name" : "Hello world!"
     }
   ...
     "_score" : 0.0,
     "_source" : {
       "name" : "Hello world! I am Sam."
     }
   ...

Если вам не нужен полнотекстовый поиск или оценка, фильтры предпочтительнее, потому что Elasticsearch автоматически использует кешируемые фильтры для повышения производительности. См. Elasticsearch: Запрос и контекст фильтра.


11

Еще немного дополнений к тому же. Сначала применяется фильтр, а затем запрос обрабатывается по его результатам. Для хранения двоичного соответствия истина / ложь для каждого документа используется нечто, называемое массивом bitSet. Этот массив BitSet находится в памяти, и он будет использоваться со второго раза, когда фильтр запрашивается. Таким образом, используя структуру данных массива bitset, мы можем использовать кэшированный результат.

Здесь следует отметить еще один момент: кэш фильтра создается только тогда, когда запрос выполняется, следовательно, только после второго попадания, мы фактически получаем преимущество кеширования.

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


1
Интересный! Я не понимал, что фильтры происходят до запросов. Кэширование фильтров теперь имеет больше смысла.
Постоянный Мейринг

Не всегда. Основная и основная разница между фильтрованным запросом и запросом с постоянной оценкой. Постоянная оценка всегда сначала выполняет запрос, а затем применяет к нему фильтр. Даже фильтрованный запрос имеет настройки, по которым запрос может выполняться перед фильтрами.
piyushGoyal

10

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

Например, скажем, у вас есть индекс ресторанов что-то вроде Zomato. Теперь вы хотите искать рестораны, которые подают «пиццу» , которая в основном является вашим ключевым словом поиска.

Таким образом, вы будете использовать запрос, чтобы найти все документы, содержащие «пиццу», и некоторые результаты будут получены.

Допустим, вам нужен список ресторанов, где подают пиццу и рейтинг не ниже 4.0.

Так что вам нужно будет использовать ключевое слово «пицца» в своем запросе и применить фильтр для рейтинга как 4.0.

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


Не могли бы вы привести пример тела запроса?
собака

9

Filters-> Соответствует ли этот документ? бинарный ответ да или нет

Queries-> Соответствует ли этот документ? Насколько хорошо это соответствует? использует скоринг


0

Начиная с версии 2 Elasticsearch, фильтры и запросы были объединены, и любое условие запроса может использоваться как фильтр или как запрос (в зависимости от контекста). Как и в версии 1, фильтры кэшируются и должны использоваться, если оценка не имеет значения.

Источник: https://logz.io/blog/elasticsearch-queries/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.