Оглавление курса
Теоретический курс · 2 / 6

Булевы запросы

Объединяйте условия через bool. must влияет на релевантность, filter — нет; must_not исключает документы. При наличии must или filter условия should необязательны, если не задан minimum_should_match.

Разделов: 5Elasticsearch 9.4.3Ещё не прочитан

Чему вы научитесь

  • Переводить И, ИЛИ и НЕ в условия bool.
  • Отделять допуск документа от релевантности.
  • Делать альтернативы обязательными там, где этого требует задача.

Бизнес-условия редко помещаются в одну конструкцию: товар должен подходить по тексту, быть в наличии, попадать в диапазон цены и не иметь запрещённого статуса. bool соединяет такие условия. Каждый уровень читайте как отдельное логическое выражение: соседние filter связаны через И, а should задаёт альтернативы с определённым числом обязательных совпадений.

Различие query context и filter context связано с оценкой: поиск определяет, насколько хорошо документ подходит, фильтр — только проходит ли он условие. Внешний filter подавляет scoring и у потомков, даже если вложенный bool содержит must.

Как bool допускает документ
  • must + filter: обязательно
  • must_not: исключить совпавшие
  • should: нужное число совпадений
  • Допущенный документ + score

Документ должен выполнить обязательные условия и избежать исключений. Обязательные совпадения should проверяются до ранжирования результата.

Примеры выполнены на публичном наборе products в Elasticsearch 9.4.3. Ответы — сокращённые фрагменты JSON: время, сведения о шардах и индексе опущены. Числовые оценки иллюстративны и могут меняться. Примеры объясняют способ решения; значения в заданиях могут отличаться.

01 / 05

Обязательные условия

Каждое условие bool.must обязано совпасть. В query context эти условия также участвуют в оценке. Список из match и term одновременно требует текстового совпадения и точного условия. Пример ищет gaming в name и требует наличие: это И, а не выбор между словом и логическим значением.

Одиночное условие можно записать объектом, несколько обычно записывают массивом. Выбирайте понятный единый стиль. В прикладном поиске наличие чаще удобно вынести в filter, но этот раздел отдельно показывает must: упражнение может намеренно требовать конкретный контекст.

Разберём другой сценарий

POST /products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "gaming"
          }
        },
        {
          "term": {
            "in_stock": true
          }
        }
      ]
    }
  },
  "size": 2,
  "_source": [
    "name",
    "in_stock"
  ]
}
Ответ Elasticsearch
Сокращённый ответ · JSON
{
  "hits": {
    "total": {
      "value": 20,
      "relation": "eq"
    },
    "hits": [
      {
        "_id": "4",
        "_score": 2.7367332,
        "_source": {
          "name": "Logitech Gaming Keyboard 4",
          "in_stock": true
        }
      },
      {
        "_id": "14",
        "_score": 2.7367332,
        "_source": {
          "name": "Samsung Gaming Keyboard 14",
          "in_stock": true
        }
      }
    ]
  }
}

Как читать результат

Каждый товар подходит по тексту и находится в наличии. Оценка определяется поисковыми условиями, а не количеством полей JSON.

Закрепить в задании 6
02 / 05

Фильтр без scoring

bool.filter требует выполнения каждого ограничения без добавления вклада в релевантность. Точный бренд, наличие и цена — подходящие примеры: товар не должен становиться релевантнее только из-за наличия. Если поисковых условий нет, bool только с filter обычно возвращает нулевую оценку.

Контекст распространяется на всю вложенную конструкцию. Вложенный bool с двумя фильтрами означает сгруппированное И. Сохраняйте читаемость и не создавайте уровни без необходимости. Elasticsearch может учитывать фильтры для кеширования, но корректность не должна зависеть от попадания в кеш или конкретного порядка исполнения.

УсловиеОбязательно?Добавляет score в query context?
mustДаДа
filterДаНет
must_notНе должно совпастьНет
shouldЗависит от minimum_should_matchДа

Разберём другой сценарий

POST /products/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brand.keyword": "Sony"
          }
        },
        {
          "term": {
            "in_stock": false
          }
        },
        {
          "range": {
            "price": {
              "lt": 1200
            }
          }
        }
      ]
    }
  },
  "size": 2,
  "_source": [
    "name",
    "brand",
    "price",
    "in_stock"
  ],
  "sort": [
    {
      "id": "asc"
    }
  ]
}
Ответ Elasticsearch
Сокращённый ответ · JSON
{
  "hits": {
    "total": {
      "value": 40,
      "relation": "eq"
    },
    "hits": [
      {
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "Sony Travel Speaker 3",
          "brand": "Sony",
          "price": 100,
          "in_stock": false
        }
      },
      {
        "_id": "15",
        "_score": null,
        "_source": {
          "name": "Sony USB Cable 15",
          "brand": "Sony",
          "price": 499,
          "in_stock": false
        }
      }
    ]
  }
}

Как читать результат

Товары выполняют все три ограничения. Сортировка по id стабилизирует просмотр; нулевой или null-score в таком ответе не означает ошибку.

Закрепить в задании 7
03 / 05

Исключение товаров

Условие must_not исключает документ, если внутренний запрос совпал. При нескольких must_not ни одно из них не должно совпасть: исключение статуса A и статуса B убирает обе группы. Это не требование отличаться только от одного значения.

bool только с must_not начинает со всех документов и вычитает совпадения. Поэтому отсутствующие значения могут остаться: документ без status не совпадает с term status: preorder и этим условием не исключается. Если нужно наличие поля, добавьте exists как отдельное обязательное условие.

Разберём другой сценарий

POST /products/_search
{
  "query": {
    "bool": {
      "must_not": [
        {
          "term": {
            "status": "preorder"
          }
        }
      ]
    }
  },
  "size": 2,
  "_source": [
    "name",
    "status"
  ],
  "sort": [
    {
      "id": "asc"
    }
  ]
}
Ответ Elasticsearch
Сокращённый ответ · JSON
{
  "hits": {
    "total": {
      "value": 200,
      "relation": "eq"
    },
    "hits": [
      {
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "Reference device",
          "status": "discontinued"
        }
      },
      {
        "_id": "3",
        "_score": null,
        "_source": {
          "name": "Sony Travel Speaker 3",
          "status": "active"
        }
      }
    ]
  }
}

Как читать результат

Ни один возвращённый товар не имеет preorder. Запрос намеренно оставляет active и discontinued: он показывает исключение, а не полную политику доступности.

Закрепить в задании 8
04 / 05

Альтернативные бренды

should задаёт альтернативы. В примере это категории, а не бренды: достаточно Audio или Accessories. minimum_should_match: 1 явно фиксирует ИЛИ, хотя bool только с should и так по умолчанию требует одно совпадение. Явное значение особенно важно при добавлении обязательных условий.

Каждая альтернатива может быть целым деревом запроса. Для (A И B) ИЛИ (C И D) поместите в should две вложенные bool-группы, а не четыре независимых условия. В финальном уроке такое группирование связывает категории с разными диапазонами цен.

ABA И BA ИЛИ B
ложьложьложьложь
ложьистиналожьистина
истиналожьложьистина
истинаистинаистинаистина

Разберём другой сценарий

POST /products/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "category": "Audio"
          }
        },
        {
          "term": {
            "category": "Accessories"
          }
        }
      ],
      "minimum_should_match": 1
    }
  },
  "size": 2,
  "_source": [
    "name",
    "category"
  ],
  "sort": [
    {
      "id": "asc"
    }
  ]
}
Ответ Elasticsearch
Сокращённый ответ · JSON
{
  "hits": {
    "total": {
      "value": 150,
      "relation": "eq"
    },
    "hits": [
      {
        "_id": "2",
        "_score": null,
        "_source": {
          "name": "Reference device",
          "category": "Audio"
        }
      },
      {
        "_id": "4",
        "_score": null,
        "_source": {
          "name": "Logitech Gaming Keyboard 4",
          "category": "Accessories"
        }
      }
    ]
  }
}

Как читать результат

Каждый товар относится хотя бы к одной разрешённой категории. Обе одновременно не требуются, что важно для нашего однозначного category.

Закрепить в задании 9
05 / 05

Минимум совпадений

minimum_should_match задаётся в том bool, чьими should он управляет. При наличии must или filter значение по умолчанию равно нулю; без них — единице. Для «не меньше двух признаков» задайте число явно. Пример требует два из трёх слов в name и одновременно ограничивает наличие.

Подсчитываются совпавшие условия should, а не число терминов одного match. Один match с несколькими словами всё ещё является одним should-условием. Для отдельно учитываемых признаков нужны отдельные конструкции; внутри каждой match анализатор продолжает обрабатывать регистр и токены.

Разберём другой сценарий

POST /products/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "in_stock": true
          }
        }
      ],
      "should": [
        {
          "match": {
            "name": "wireless"
          }
        },
        {
          "match": {
            "name": "premium"
          }
        },
        {
          "match": {
            "name": "mouse"
          }
        }
      ],
      "minimum_should_match": 2
    }
  },
  "size": 2,
  "_source": [
    "name",
    "in_stock"
  ]
}
Ответ Elasticsearch
Сокращённый ответ · JSON
{
  "hits": {
    "total": {
      "value": 39,
      "relation": "eq"
    },
    "hits": [
      {
        "_id": "7",
        "_score": 3.2707968,
        "_source": {
          "name": "Apple Wireless Mouse 7",
          "in_stock": true
        }
      },
      {
        "_id": "17",
        "_score": 3.2707968,
        "_source": {
          "name": "Dell Wireless Mouse 17",
          "in_stock": true
        }
      }
    ]
  }
}

Как читать результат

Подходящее название содержит как минимум два запрошенных словесных признака. Одного совпадения по наличию недостаточно.

Закрепить в задании 10

Краткая памятка

  • must — обязательное поисковое совпадение; filter — обязательный допуск.
  • must_not исключает документы, совпавшие хотя бы с одним исключением.
  • Значение should по умолчанию меняется при наличии must или filter.
  • minimum_should_match считает условия, а не слова внутри match.
  • Сначала группируйте ветви И, затем соединяйте их через ИЛИ.

Официальная документация

Готовы применить знания?

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