в OpenSearch интервальный запрос - это тип запроса, который обеспечивает тонкий контроль над словами и их позициями в тексте, необходимыми для того, чтобы документ соответствовал запросу.
Как реализовать запрос с интервалами
На верхнем уровне запроса находится поле для поиска, за которым следует любое количество следующих пунктов, как описано ниже:
- match
- prefix
- fuzzy
- wildcard
- all_of (используется для создания цепочки из нескольких условий в виде AND)
- any_of (используется для цепочки нескольких условий как ИЛИ)
Match
- query - текст, который мы ищем
- max_gaps (по умолчанию -1), -1 = нет ограничений на расстояние между словами 0 = слова вместе
- "ordered" : true - слова должны быть найдены в том порядке, в котором они выражены в запросе
Prefix
- query - искомый текст в качестве префикса к любому слову в тексте
Fuzzy
- query - искомый текст
- Fuzziness - количество правок, необходимых для перехода от запроса к слову в тексте
Wildcard
- pattern - строка, содержащая ? для любого отдельного символа или * для 0 или более символов.
Например: 123?4*6 будет соответствовать 123A456 или 123B4something6, но не 123something456 - use_field - необязательный параметр, если вы хотите использовать поле, отличное от поля верхнего уровня
- analyzer - необязательный параметр, если вы хотите использовать другой поисковый анализатор для нормализации шаблона.
All_of
- intervals - список подпунктов правила, которые должны быть сопоставлены
- max_gaps - (по умолчанию -1), -1 = нет ограничений на расстояние между словами 0 = слова должны быть вместе
- ordered true/false: пункты правил должны встречаться в тексте в том порядке, в котором они выражены в запросе
Any_of
- intervals - список подпунктов правила, где хотя бы один из них должен встречаться в тексте
Пример интервального запроса
В приведенном ниже запросе используются оба значения "all_of" и "any_of" (AND OR).
Нижеприведенный запрос будет соответствовать:
- if you go down to the woods today you’re in for a big surprise
- if you go down to the woods today you’ll never believe your eyes
Не соответствует:
- if you go down to the green woods today you’re in for a big surprise (потому что максимальные пробелы:0)
- you’re in for a big surprise if you go down to the woods today (из-за "ordered:true)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | POST _search { "query": { "intervals" : { "my_field" : { "all_of" : { "ordered" : true, "intervals" : [ { "match" : { "query" : "if you go down to the woods", "max_gaps" : 0, "ordered" : true } }, { "any_of" : { "intervals" : [ { "match" : { "query" : "big surprise" } }, { "match" : { "query" : "eyes" } } ] } } ] } } } } } |
Фильтры в OpenSearch
Фильтры используются для добавления дополнительных условий к правилам.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | POST content_articles_v7/_search { "query": { "intervals" : { "content.en.short_description" : { "match" : { "query" : "reconstruction substations", "max_gaps" : 9, "filter" : { "not_containing" : { "match" : { "query" : "heating" } } } } } } } } |
Приведенный выше запрос вернет "reconstruction of electrical substations", но не "reconstruction of heating substations".
В следующем примере используется скрипт для фильтрации интервалов на основе их начальной и конечной позиций. Переменная может использовать:
- interval.start - Позиция, с которой начинается интервал
- interval.end - Позиция, в которой заканчивается интервал.
- interval.gaps - количество пробелов между словами
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | POST my_index/_search { "query": { "intervals" : { "my_text" : { "match" : { "query" : "hot meal", "filter" : { "script" : { "source" : "interval.start > 5 && interval.end < 30 && interval.gaps == 0" } } } } } } } |
Примечания и полезные советы
Пользователи могут получить неожиданные результаты, если использовать "any of" вместе с двумя запросами, один из которых является префиксом другого. Это происходит потому, что запрос intervals минимизирует интервалы.
Рассмотрим следующий пример, в котором ищут , сразу после "quick OR "quick brown" сразу после "fox". Вопреки ожиданиям, этот запрос не соответствует документу "the quick brown fox", потому что правило middle of any_of минимизирует варианты и рассматривает только "quick" как допустимый вариант.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | POST my_index/_search { "query": { "intervals" : { "my_text" : { "all_of" : { "intervals" : [ { "match" : { "query" : "the" } }, { "any_of" : { "intervals" : [ { "match" : { "query" : "quickl" } }, { "match" : { "query" : "quick brown" } } ] } }, { "match" : { "query" : "fox" } } ], "max_gaps" : 0, "ordered" : true } } } } } |
По этой причине вам следует явно указать опции на верхнем уровне, как показано здесь:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | POST my_index/_search { "query": { "intervals" : { "my_text" : { "any_of" : { "intervals" : [ { "match" : { "query" : "the quick brown fox", "ordered" : true, "max_gaps" : 0 } }, { "match" : { "query" : "the quick fox", "ordered" : true, "max_gaps" : 0 } } ] } } } } } |