intervals query

Позволяет точно контролировать близость и порядок совпадающих терминов.

Запрос интервалов

Запрос интервалов сопоставляет документы на основе близости и порядка совпадающих терминов. Он применяет набор правил сопоставления к терминам, содержащимся в указанном поле. Запрос генерирует последовательности минимальных интервалов, охватывающих термины в тексте. Вы можете комбинировать интервалы и фильтровать их по родительским источникам.

Рассмотрим индекс, содержащий следующие документы:

PUT testindex/_doc/1 
{
  "title": "пары ключ-значение эффективно хранятся в хэш-таблице"
}

PUT /testindex/_doc/2
{
  "title": "хранить пары ключ-значение в хэш-карте"
}

Например, следующий запрос ищет документы, содержащие фразу “пары ключ-значение” (без промежутков между терминами), за которой следует либо “хэш-таблица”, либо “хэш-карта”:

GET /testindex/_search
{
  "query": {
    "intervals": {
      "title": {
        "all_of": {
          "ordered": true,
          "intervals": [
            {
              "match": {
                "query": "пары ключ-значение",
                "max_gaps": 0,
                "ordered": true
              }
            },
            {
              "any_of": {
                "intervals": [
                  {
                    "match": {
                      "query": "хэш-таблица"
                    }
                  },
                  {
                    "match": {
                      "query": "хэш-карта"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

Запрос возвращает оба документа.


Параметры

Запрос принимает имя поля (<field>) в качестве параметра верхнего уровня:

GET _search
{
  "query": {
    "intervals": {
      "<field>": {
        ... 
      }
    }
  }
}

Поле <field> принимает следующие объекты правил, которые используются для сопоставления документов на основе терминов, порядка и близости.

Правило Описание
match Сопоставляет анализируемый текст.
prefix Сопоставляет термины, которые начинаются с заданного набора символов.
wildcard Сопоставляет термины, используя шаблон с подстановочными знаками.
fuzzy Сопоставляет термины, которые похожи на предоставленный термин в пределах заданного расстояния редактирования.
all_of Объединяет несколько правил с использованием конъюнкции (AND).
any_of Объединяет несколько правил с использованием дизъюнкции (OR).

Правило match

Правило match сопоставляет анализируемый текст. В следующей таблице перечислены все параметры, которые поддерживает правило match.

Параметр Обязательный/Необязательный Тип данных Описание
query Обязательный Строка Текст, по которому нужно выполнить поиск.
analyzer Необязательный Строка Анализатор, используемый для анализа текста запроса. По умолчанию используется анализатор, указанный для <field>.
filter Необязательный Объект правила фильтра интервалов Правило, используемое для фильтрации возвращаемых интервалов.
max_gaps Необязательный Целое число Максимально допустимое количество позиций между совпадающими терминами. Термины, находящиеся дальше, чем max_gaps, не считаются совпадениями. Если max_gaps не указан или установлен в -1, термины считаются совпадениями независимо от их положения. Если max_gaps установлен в 0, совпадающие термины должны находиться рядом друг с другом. По умолчанию -1.
ordered Необязательный Логическое Указывает, должны ли совпадающие термины появляться в указанном порядке. По умолчанию false.
use_field Необязательный Строка Указывает, что следует искать в этом поле вместо верхнего уровня. Термины анализируются с использованием анализатора поиска, указанного для этого поля. Указав use_field, вы можете искать по нескольким полям, как если бы они были одним и тем же полем. Например, если вы индексируете один и тот же текст в полях с корнями и без корней, вы можете искать корневые токены, которые находятся рядом с некорневыми.

Правило prefix

Правило prefix сопоставляет термины, которые начинаются с заданного набора символов (префикс). Префикс может расширяться для сопоставления максимум 128 терминов. Если префикс соответствует более чем 128 терминам, возвращается ошибка. В следующей таблице перечислены все параметры, которые поддерживает правило prefix.

Параметр Обязательный/Необязательный Тип данных Описание
prefix Обязательный Строка Префикс, используемый для сопоставления терминов.
analyzer Необязательный Строка Анализатор, используемый для нормализации префикса. По умолчанию используется анализатор, указанный для <field>.
use_field Необязательный Строка Указывает, что следует искать в этом поле вместо верхнего уровня. Префикс нормализуется с использованием анализатора поиска, указанного для этого поля, если вы не укажете analyzer.

Правило wildcard

Правило wildcard сопоставляет термины, используя шаблон с подстановочными знаками. Шаблон с подстановочными знаками может расширяться для сопоставления максимум 128 терминов. Если шаблон соответствует более чем 128 терминам, возвращается ошибка. В следующей таблице перечислены все параметры, которые поддерживает правило wildcard.

Параметр Обязательный/Необязательный Тип данных Описание
pattern Обязательный Строка Шаблон с подстановочными знаками, используемый для сопоставления терминов. Укажите ? для сопоставления любого одного символа или * для сопоставления нуля или более символов.
analyzer Необязательный Строка Анализатор, используемый для нормализации шаблона. По умолчанию используется анализатор, указанный для <field>.
use_field Необязательный Строка Указывает, что следует искать в этом поле вместо верхнего уровня. Шаблон нормализуется с использованием анализатора поиска, указанного для этого поля, если вы не укажете analyzer.

Указание шаблонов, начинающихся с * или ?, может ухудшить производительность поиска, так как увеличивает количество итераций, необходимых для сопоставления терминов.

Правило fuzzy

Правило fuzzy сопоставляет термины, которые похожи на предоставленный термин в пределах заданного расстояния редактирования. Шаблон fuzzy может расширяться для сопоставления максимум 128 терминов. Если шаблон соответствует более чем 128 терминам, возвращается ошибка. В следующей таблице перечислены все параметры, которые поддерживает правило fuzzy.

Параметр Обязательный/Необязательный Тип данных Описание
term Обязательный Строка Термин для сопоставления.
analyzer Необязательный Строка Анализатор, используемый для нормализации термина. По умолчанию используется анализатор, указанный для <field>.
fuzziness Необязательный Строка Количество редактирований символов (вставка, удаление, замена), необходимых для изменения одного слова на другое при определении, совпадает ли термин со значением. Например, расстояние между “wined” и “wind” равно 1. Допустимые значения — неотрицательные целые числа или AUTO. По умолчанию AUTO выбирает значение на основе длины каждого термина и является хорошим выбором для большинства случаев использования.
transpositions Необязательный Логическое Установка transpositions в true (по умолчанию) добавляет обмены соседних символов к операциям вставки, удаления и замены в параметре fuzziness. Например, расстояние между “wind” и “wnid” равно 1, если transpositions равно true (обмен “n” и “i”), и 2, если false (удаление “n”, вставка “n”). Если transpositions равно false, “rewind” и “wnid” имеют одинаковое расстояние (2) от “wind”, несмотря на более человеческое мнение, что “wnid” является очевидной опечаткой. По умолчанию является хорошим выбором для большинства случаев использования.
prefix_length Необязательный Целое число Количество начальных символов, оставляемых неизменными для нечеткого сопоставления. По умолчанию 0.
use_field Необязательный Строка Указывает, что следует искать в этом поле вместо верхнего уровня. Термин нормализуется с использованием анализатора поиска, указанного для этого поля, если вы не укажете analyzer.

Правило all_of

Правило all_of объединяет несколько правил с использованием конъюнкции (AND). В следующей таблице перечислены все параметры, которые поддерживает правило all_of.

Параметр Обязательный/Необязательный Тип данных Описание
intervals Обязательный Массив объектов правил Массив правил для объединения. Документ должен соответствовать всем правилам, чтобы быть возвращенным в результатах.
filter Необязательный Объект правила фильтра интервалов Правило, используемое для фильтрации возвращаемых интервалов.
max_gaps Необязательный Целое число Максимально допустимое количество позиций между совпадающими терминами. Термины, находящиеся дальше, чем max_gaps, не считаются совпадениями. Если max_gaps не указан или установлен в -1, термины считаются совпадениями независимо от их положения. Если max_gaps установлен в 0, совпадающие термины должны находиться рядом друг с другом. По умолчанию -1.
ordered Необязательный Логическое Если true, интервалы, сгенерированные правилами, должны появляться в указанном порядке. По умолчанию false.

Правило any_of

Правило any_of объединяет несколько правил с использованием дизъюнкции (OR). В следующей таблице перечислены все параметры, которые поддерживает правило any_of.

Параметр Обязательный/Необязательный Тип данных Описание
intervals Обязательный Массив объектов правил Массив правил для объединения. Документ должен соответствовать хотя бы одному правилу, чтобы быть возвращенным в результатах.
filter Необязательный Объект правила фильтра интервалов Правило, используемое для фильтрации возвращаемых интервалов.

Правило filter

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

Параметр Обязательный/Необязательный Тип данных Описание
after Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые следуют за интервалом, указанным в правиле фильтра.
before Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые находятся перед интервалом, указанным в правиле фильтра.
contained_by Необязательный Объект запроса Запрос, используемый для возврата интервалов, содержащихся в интервале, указанном в правиле фильтра.
containing Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые содержат интервал, указанный в правиле фильтра.
not_contained_by Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые не содержатся в интервале, указанном в правиле фильтра.
not_containing Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые не содержат интервал, указанный в правиле фильтра.
not_overlapping Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые не перекрываются с интервалом, указанным в правиле фильтра.
overlapping Необязательный Объект запроса Запрос, используемый для возврата интервалов, которые перекрываются с интервалом, указанным в правиле фильтра.
script Необязательный Объект скрипта Скрипт, используемый для сопоставления документов. Этот скрипт должен возвращать true или false.

Пример: Фильтры

Следующий запрос ищет документы, содержащие слова “пары” и “хэш”, которые находятся в пределах пяти позиций друг от друга и не содержат слово “эффективно” между ними:

POST /testindex/_search
{
  "query": {
    "intervals" : {
      "title" : {
        "match" : {
          "query" : "пары хэш",
          "max_gaps" : 5,
          "filter" : {
            "not_containing" : {
              "match" : {
                "query" : "эффективно"
              }
            }
          }
        }
      }
    }
  }
}

Ответ содержит только документ 2.

Ответ

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.25,
    "hits": [
      {
        "_index": "testindex",
        "_id": "2",
        "_score": 0.25,
        "_source": {
          "title": "хранить пары ключ-значение в хэш-карте"
        }
      }
    ]
  }
}

Пример: Скриптовые фильтры

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

  • interval.start: Позиция (номер термина), где начинается интервал.
  • interval.end: Позиция (номер термина), где заканчивается интервал.
  • interval.gap: Количество слов между терминами.

Например, следующий запрос ищет слова “карта” и “хэш”, которые находятся рядом друг с другом в указанном интервале. Термины нумеруются, начиная с 0, поэтому в тексте “хранить пары ключ-значение в хэш-карте” слово “хранить” находится на позиции 0, “пары” на позиции 1 и так далее. Указанный интервал должен начинаться после “а” и заканчиваться перед концом строки:

POST /testindex/_search
{
  "query": {
    "intervals" : {
      "title" : {
        "match" : {
          "query" : "карта хэш",
          "filter" : {
            "script" : {
              "source" : "interval.start > 5 && interval.end < 8 && interval.gaps == 0"
            }
          }
        }
      }
    }
  }
}

Ответ

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.5,
    "hits": [
      {
        "_index": "testindex",
        "_id": "2",
        "_score": 0.5,
        "_source": {
          "title": "хранить пары ключ-значение в хэш-карте"
        }
      }
    ]
  }
}

Минимизация интервалов

Чтобы гарантировать, что запросы выполняются за линейное время, запрос интервалов минимизирует интервалы. Например, рассмотрим документ, содержащий текст “a b c d c”. Вы можете использовать следующий запрос для поиска “d”, который содержится между “a” и “c”:

POST /testindex/_search
{
  "query": {
    "intervals" : {
      "my_text" : {
        "match" : {
          "query" : "d",
          "filter" : {
            "contained_by" : {
              "match" : {
                "query" : "a c"
              }
            }
          }
        }
      }
    }
  }
}

Запрос не возвращает результатов, потому что он сопоставляет первые два термина “a” и “c” и не находит “d” между этими терминами.