Spec-Zone.ru › Elasticsearch 7
›Elasticsearch Guide [7.17] ›Query DSL ›Полные текстовые запросы

Запрос Common Terms

Устарело в версии 7.3.0.

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

Запрос common terms — это современная альтернатива стоп-словам, которая улучшает точность и полноту результатов поиска (принимая во внимание стоп-слова), не жертвуя производительностью.

Проблема

Каждый термин в запросе имеет стоимость. Поиск "The brown fox" требует трёх запросов по термин, по одному для каждого из "the", "brown" и "fox", все из которых выполняются для всех документов в индексе. Запрос для "the", скорее всего, будет соответствовать многим документам и, следовательно, окажет гораздо меньшее влияние на релевантность, чем два других термина.

Ранее решением этой проблемы было игнорирование терминов с высокой частотой. Обработка "the" как стоп-слова сокращает размер индекса и уменьшает количество запросов по терминам, которые необходимо выполнить.

Проблема такого подхода заключается в том, что, хотя стоп-слова оказывают незначительное влияние на релевантность, они всё же важны. Если мы удалим стоп-слова, мы потеряем точность (например, мы не сможем отличить "happy" от "not happy") и полноту (например, текст, подобный "The The" или "To be or not to be", просто не будет существовать в индексе).

Решение

Запрос common terms разделяет термины запроса на две группы: более важные (т.е. термины с низкой частотой) и менее важные (т.е. термины с высокой частотой, которые ранее были стоп-словами).

Сначала он ищет документы, которые соответствуют более важным терминам. Это термины, которые встречаются в меньшем количестве документов и оказывают большее влияние на релевантность.

Затем он выполняет второй запрос по менее важным терминам — терминам, которые встречаются часто и оказывают малое влияние на релевантность. Но вместо расчёта оценки релевантности для всех соответствующих документов, он рассчитывает только _score для документов, уже соответствующих первому запросу. Таким образом, термины высокой частоты могут улучшить вычисление релевантности, не оплачивая стоимость низкой производительности.

Если запрос состоит только из терминов высокой частоты, то выполняется один запрос как запрос AND (конъюнкция), то есть все термины необходимы. Несмотря на то, что каждый отдельный термин будет соответствовать многим документам, сочетание терминов сужает результат до самых релевантных. Единственный запрос также может быть выполнен как OR со значением minimum_should_match, в этом случае, вероятно, следует использовать достаточно большое значение.

Термины распределяются по группам высокой и низкой частоты на основе cutoff_frequency, которое может быть указано как абсолютная частота (>=1) или относительная частота (0.0 .. 1.0). (Помните, что частоты документов вычисляются на уровне фрагмента, как объясняется в блоге Relevance is broken.)

Возможно, самой интересной особенностью этого запроса является то, что он автоматически адаптируется к стоп-словам, специфичным для предметной области. Например, на сайте хостинга видео распространённые термины, такие как "clip" или "video", автоматически будут вести себя как стоп-слова, без необходимости поддерживать список вручную.

Примеры

В этом примере слова, имеющие частоту документов, большую чем 0,1% (например, "this" и "is"), будут рассматриваться как общие термины.

GET /_search
{
  "query": {
    "common": {
      "body": {
        "query": "this is bonsai cool",
        "cutoff_frequency": 0.001
      }
    }
  }
}

Количество терминов, которые должны совпадать, можно контролировать с помощью minimum_should_match (high_freq, low_freq), low_freq_operator (по умолчанию "or") и high_freq_operator (по умолчанию "or") параметров.

Для терминов низкой частоты установите low_freq_operator в значение "and", чтобы сделать все термины обязательными:

GET /_search
{
  "query": {
    "common": {
      "body": {
        "query": "nelly the elephant as a cartoon",
        "cutoff_frequency": 0.001,
        "low_freq_operator": "and"
      }
    }
  }
}

что примерно эквивалентно:

GET /_search
{
  "query": {
    "bool": {
      "must": [
      { "term": { "body": "nelly"}},
      { "term": { "body": "elephant"}},
      { "term": { "body": "cartoon"}}
      ],
      "should": [
      { "term": { "body": "the"}},
      { "term": { "body": "as"}},
      { "term": { "body": "a"}}
      ]
    }
  }
}

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

GET /_search
{
  "query": {
    "common": {
      "body": {
        "query": "nelly the elephant as a cartoon",
        "cutoff_frequency": 0.001,
        "minimum_should_match": 2
      }
    }
  }
}

что примерно эквивалентно:

GET /_search
{
  "query": {
    "bool": {
      "must": {
        "bool": {
          "should": [
            { "term": { "body": "nelly"}},
            { "term": { "body": "elephant"}},
            { "term": { "body": "cartoon"}}
          ],
          "minimum_should_match": 2
        }
      },
      "should": [
        { "term": { "body": "the"}},
        { "term": { "body": "as"}},
        { "term": { "body": "a"}}
      ]
    }
  }
}

Разные minimum_should_match могут применяться для терминов низкой и высокой частоты с дополнительными low_freq и high_freq параметрами. Вот пример с дополнительными параметрами (обратите внимание на изменение структуры):

GET /_search
{
  "query": {
    "common": {
      "body": {
        "query": "nelly the elephant not as a cartoon",
        "cutoff_frequency": 0.001,
        "minimum_should_match": {
          "low_freq": 2,
          "high_freq": 3
        }
      }
    }
  }
}

что примерно эквивалентно:

GET /_search
{
  "query": {
    "bool": {
      "must": {
        "bool": {
          "should": [
            { "term": { "body": "nelly"}},
            { "term": { "body": "elephant"}},
            { "term": { "body": "cartoon"}}
          ],
          "minimum_should_match": 2
        }
      },
      "should": {
        "bool": {
          "should": [
            { "term": { "body": "the"}},
            { "term": { "body": "not"}},
            { "term": { "body": "as"}},
            { "term": { "body": "a"}}
          ],
          "minimum_should_match": 3
        }
      }
    }
  }
}

В данном случае это означает, что термины высокой частоты влияют на релевантность только тогда, когда их не менее трёх. Но самое интересное применение minimum_should_match для терминов высокой частоты — это когда имеются только термины высокой частоты:

GET /_search
{
  "query": {
    "common": {
      "body": {
        "query": "how not to be",
        "cutoff_frequency": 0.001,
        "minimum_should_match": {
          "low_freq": 2,
          "high_freq": 3
        }
      }
    }
  }
}

что примерно эквивалентно:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "term": { "body": "how"}},
        { "term": { "body": "not"}},
        { "term": { "body": "to"}},
        { "term": { "body": "be"}}
      ],
      "minimum_should_match": "3<50%"
    }
  }
}

Сгенерированный запрос высокой частоты в этом случае немного менее ограничен, чем при использовании запроса AND.

Запрос common terms также поддерживает boost и analyzer в качестве параметров.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-common-terms-query.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API