Поиск частично введенных слов и шаблоны со специальными символами (дефисы, подстановочные знаки, регулярные выражения, шаблоны)
Частичный поиск терминов относится к запросам, состоящим из фрагментов терминов, где вместо целого термина может быть только начало, середина или конец термина (иногда называется префиксом, infix или суффикс запросами). Такой поиск может включать комбинацию фрагментов, часто со специальными символами, такими как дефисы, тире или косая черта, которые являются частью строки запроса. Это могут быть фрагменты номера телефона, URL-адреса, кодов или составных слов с дефисами.
Частичные термины и специальные символы могут быть проблематичными, если индекс не имеет маркера, представляющего фрагмент текста, который требуется найти. Во время этапа лексического анализа индексирования ключевых слов (при условии стандартного анализатора по умолчанию) специальные символы удаляются, составные слова разбиваются, а пробелы удаляются. Если вы ищете фрагмент текста, измененный во время лексического анализа, запрос завершается ошибкой, так как совпадение не найдено. Рассмотрим этот пример: номер телефона, например (токенизованный как "425"
"1"
, , "703"
, ) "6214"
не отображается в "3-62"
запросе, так как +1 (425) 703-6214
содержимое на самом деле не существует в индексе.
Решение заключается в том, чтобы вызвать анализатор во время индексирования, сохраняющего полную строку, включая пробелы и специальные символы (при необходимости), чтобы можно было включать пробелы и символы в строку запроса. В целом неуправляемая строка обеспечивает сопоставление шаблонов для запросов "начинается с" или "заканчивается запросами", где предоставленный шаблон можно оценить по термину, который не преобразуется в лексический анализ.
Если вам нужно поддерживать сценарии поиска, которые вызывают проанализированное и неанализированное содержимое, рассмотрите возможность создания двух полей в индексе, по одному для каждого сценария. Одно поле проходит лексический анализ. Второе поле сохраняет нетронутую строку с помощью анализатора, сохраняющего содержимое, который выдает маркеры целостроковых строк для сопоставления шаблонов.
Информация о поиске частично введенных слов
Поиск azure AI сканирует целые токенизованные термины в индексе и не находит совпадение по частичному термину, если вы не включаете операторы заполнителей подстановочных знаков (*
и) или ?
форматируете запрос в виде регулярного выражения.
Частично введенные слова указываются с помощью следующих методов:
Запросы регулярных выражений могут быть любым регулярным выражением, допустимым в Apache Lucene.
Подстановочные знаки с сопоставлением префиксов относятся к общепризнанной схеме, которая включает начало термина, за которым следует
*
или?
суффикс операторов, напримерsearch=cap*
сопоставление в Cap'n Jack's Waterfront Inn или Highline Capital. Сопоставление префикса поддерживается как в простом, так и в полном синтаксисе запроса Lucene.Подстановочный знак с инфиксным и суффиксным сопоставлением помещает операторы
*
и?
в начало слова и требует использования синтаксиса регулярного выражения (где выражение заключено в символы косой черты). Например, строка запроса (search=/.*numeric.*/
) возвращает результаты по буквенным и буквенно-цифровым символам в виде суффикса и инфикса.
Для регулярного выражения, подстановочного знака и нечеткого поиска анализаторы не используются во время запроса. Для этих форм запросов, которые синтаксический анализатор обнаруживает при наличии операторов и разделителей, строка запроса передается в ядро без лексического анализа. Для этих форм запросов анализатор, указанный в поле, игнорируется.
Примечание.
Если частичная строка запроса содержит символы, такие как косая черта во фрагменте URL-адреса, может потребоваться добавить escape-символы. В JSON прямая косая черта /
преобразуется в обратную косую черту \
. Таким образом, search=/.*microsoft.com\/azure\/.*/
является синтаксисом фрагмента URL-адреса “microsoft.com/azure/”.
Решение проблем с поиском частично введенных слов и шаблонов
Если необходимо выполнить поиск по фрагментам, или шаблонам, или специальным символам, можно переопределить анализатор по умолчанию с помощью пользовательского анализатора, работающего в более простых правилах разметки, оставив всю строку в индексе.
Такой подход выглядит следующим образом:
- Определите второе поле для хранения нетронутой версии строки (если требуется проанализировать и неанализируемый текст во время запроса)
- Оцените и выберите один из различных анализаторов, которые выдают маркеры с нужной степенью детализации.
- Назначьте анализатор полю
- Создание и тестирование индекса
1. Создание выделенного поля
Анализаторы определяют, как слова размечены в индексе. Поскольку анализаторы назначаются для каждого поля, можно создавать поля в индексе для оптимизации различных сценариев. Например, можно определить “featureCode” и “featureCodeRegex” для поддержки обычного полнотекстового поиска в первом и расширенного сопоставления шаблонов во втором. Анализаторы, назначенные каждому полю, определяют, как содержимое каждого поля размечено в индексе.
{
"name": "featureCode",
"type": "Edm.String",
"retrievable": true,
"searchable": true,
"analyzer": null
},
{
"name": "featureCodeRegex",
"type": "Edm.String",
"retrievable": true,
"searchable": true,
"analyzer": "my_custom_analyzer"
},
2. Установка анализатора
При выборе анализатора, создающего маркеры полного слова, доступны следующие анализаторы.
Анализатор | Поведение |
---|---|
Языковые анализаторы | Сохраняет дефисы в составных словах и строках, умлауты и формы глаголов. Если шаблоны запросов содержат тире, может быть достаточно использования анализатора языка. |
keyword | Содержимое всего поля размечено как одно слово. |
whitespace | Разделяется только на пробелы. Слова, содержащие дефисы или другие символы, рассматриваются как один маркер. |
Пользовательский анализатор | (рекомендуется) Создание пользовательского анализатора позволяет указать как создатель маркеров, так и фильтр маркеров. Предыдущие анализаторы должны использоваться "как есть". Пользовательский анализатор позволяет выбрать создатели маркеров и фильтры маркеров. Рекомендуемым сочетанием является создатель маркеров с ключевым словом и фильтр маркеров нижнего регистра. По сути, встроенный анализатор ключевых слов не имеет нижнего регистра любого текста верхнего регистра, что может привести к сбою запросов. Пользовательский анализатор позволяет добавить фильтр маркеров нижнего регистра. |
С помощью клиента REST можно добавить вызов REST анализатора тестирования для проверки маркеризованных выходных данных.
Индекс должен существовать в службе поиска, но он может быть пустым. При наличии существующего индекса и поля, содержащего дефисы или частично введенные слова, можно попробовать различные анализаторы для определенных слов, чтобы узнать, какие токены будут выдаваться.
Сначала попробуйте стандартный анализатор, чтобы увидеть, как слова размечены по умолчанию.
{ "text": "SVP10-NOR-00", "analyzer": "standard" }
Оцените ответ, чтобы увидеть, как текст размечен в индексе. Обратите внимание, что все слова имеют низкий регистр, дефисы удалены, а подстроки разбиты на отдельные маркеры. Только те запросы, которые соответствуют этим маркерам, будут возвращать этот документ в результатах. Запрос, включающий “10-NOR”, завершится ошибкой.
{ "tokens": [ { "token": "svp10", "startOffset": 0, "endOffset": 5, "position": 0 }, { "token": "nor", "startOffset": 6, "endOffset": 9, "position": 1 }, { "token": "00", "startOffset": 10, "endOffset": 12, "position": 2 } ] }
Теперь измените запрос, чтобы использовать анализатор
whitespace
илиkeyword
.{ "text": "SVP10-NOR-00", "analyzer": "keyword" }
На этот раз ответ состоит из одного маркера, верхнего регистра, с дефисами, сохраненными как часть строки. Если необходимо выполнить поиск по шаблону или частично введенному слову, например “10-NOR”, механизм запросов теперь имеет базу для поиска соответствия.
{ "tokens": [ { "token": "SVP10-NOR-00", "startOffset": 0, "endOffset": 12, "position": 0 } ] }
Внимание
Имейте в виду, что средства синтаксического анализа запросов часто преобразуют буквы в нижний регистр в выражении поиска при построении дерева запросов. Если вы используете анализатор, который не преобразовывает текстовые входные данные в нижний регистр во время индексирования и не получаете ожидаемые результаты, это может быть причиной. Чтобы решить эту проблему, попробуйте добавить фильтр маркеров нижнего регистра, как описано в разделе "Использование пользовательских анализаторов" ниже.
3. Настройка анализатора
Независимо от того, выполняете ли вы оценку анализаторов или перемещаетесь с определенной конфигурацией, необходимо указать анализатор в определении поля и, возможно, настроить сам анализатор, если вы не используете встроенный анализатор. При переключении анализаторов обычно требуется перестроить индекс (удалить, повторно создать и перезагрузить).
Использование встроенных анализаторов
Встроенные анализаторы можно указать по имени для analyzer
свойства определения поля без дополнительной конфигурации в индексе. В следующем примере показано, как настроить анализатор whitespace
в поле.
Другие сценарии и дополнительные сведения о других встроенных анализаторах см. в разделе Встроенные анализаторы.
{
"name": "phoneNumber",
"type": "Edm.String",
"key": false,
"retrievable": true,
"searchable": true,
"analyzer": "whitespace"
}
Использование пользовательских анализаторов
Если вы используете пользовательский анализатор, определите его в индексе с определяемым пользователем сочетанием токенизатора, фильтра маркеров с возможными параметрами конфигурации. Затем дайте ссылку на определение поля так же, как при использовании встроенного анализатора.
Если целью является разметка для полного слова, рекомендуется использовать пользовательский анализатор, состоящий из создателя маркера ключевых слов и фильтра маркеров нижнего регистра.
- Создатель маркеров ключевых слов создает один маркер для всего содержимого поля.
- Фильтр маркеров нижнего регистра преобразует прописные буквы в строчные. Синтаксические анализаторы запросов обычно преобразуют слова в верхнем регистре в нижний. Это обеспечивает единообразие введенного текста и слов с маркерами.
В следующем примере показан пользовательский анализатор, который предоставляет создатель маркеров ключевых слов и фильтр маркеров нижнего регистра.
{
"fields": [
{
"name": "accountNumber",
"analyzer":"myCustomAnalyzer",
"type": "Edm.String",
"searchable": true,
"filterable": true,
"retrievable": true,
"sortable": false,
"facetable": false
}
],
"analyzers": [
{
"@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"name":"myCustomAnalyzer",
"charFilters":[],
"tokenizer":"keyword_v2",
"tokenFilters":["lowercase"]
}
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": []
}
Примечание.
Создатель маркеров keyword_v2
и фильтр маркеров lowercase
известны системе и используют их конфигурации по умолчанию, поэтому на них можно ссылаться по имени без необходимости определения.
4. Сборка и тестирование
После определения индекса с анализаторами и определениями полей, которые поддерживают сценарий, загрузите документы с репрезентативными строками, чтобы протестировать частичные строковые запросы.
Используйте клиент REST для запроса частичных терминов и специальных символов, описанных в этой статье.
В предыдущих разделах была объяснена логика. В этом разделе описывается каждый API, который следует вызывать при тестировании решения.
Удаление индекса: удаляет существующий индекс с тем же именем, чтобы его можно было повторно создать.
Создание индекса: создает структуру индекса в службе поиска, включая определения и поля анализатора с указанием анализатора.
Загрузка документов: импортирует документы, имеющие ту же структуру, что и индекс, а также содержимое, доступное для поиска. После выполнения этого шага индекс будет готов к выполнению запроса или тестированию.
Анализатор тестов появился в мастере Установка анализатора. Проверьте некоторые строки в индексе с помощью различных анализаторов, чтобы понять, как токенизированы термины.
В разделе Документация по поиску объясняется, как создать запрос, используя простой синтаксис или полный синтаксис Lucene для подстановочных знаков и регулярных выражений.
Для запросов с частичными выражениями, таких как запрос "3-6214" для поиска совпадения в "+ 1 (425) 703-6214", можно использовать простой синтаксис:
search=3-6214&queryType=simple
.Для запросов инфиксов и суффиксов, таких как запрос “num” или “numeric” для поиска совпадений с “alphanumeric”, используйте полный синтаксис Lucene и регулярное выражение:
search=/.*num.*/&queryType=full
Оптимизация запросов префикса и суффикса
Сопоставление префиксов и суффиксов с помощью анализатора по умолчанию требует дополнительных функций запроса. Префиксы требуют поиска подстановочных знаков и суффиксов требуют поиска регулярных выражений. Обе эти функции могут снизить производительность запросов.
В следующем примере добавляется префикс EdgeNGramTokenFilter
или суффикс быстрее. Маркеры создаются в сочетаниях символов 2–25, включающих символы. Ниже приведен пример прогрессии от двух до семи маркеров: MS, MSF, MSFT, MSFT/, MSFT/S, MSFT/SQ, MSFT/SQL. EdgeNGramTokenFilter
требуется параметр, определяющий side
, из какой стороны создаются сочетания строковых символов. Используется front
для запросов префикса и back
запросов суффикса.
Дополнительная маркеризация приводит к более крупному индексу. Если у вас достаточно емкости для размещения более крупного индекса, этот подход с более быстрым временем отклика может быть лучшим решением.
{
"fields": [
{
"name": "accountNumber_prefix",
"indexAnalyzer": "ngram_front_analyzer",
"searchAnalyzer": "keyword",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": false,
"facetable": false
},
{
"name": "accountNumber_suffix",
"indexAnalyzer": "ngram_back_analyzer",
"searchAnalyzer": "keyword",
"type": "Edm.String",
"searchable": true,
"filterable": false,
"retrievable": true,
"sortable": false,
"facetable": false
}
],
"analyzers": [
{
"@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"name":"ngram_front_analyzer",
"charFilters":[],
"tokenizer":"keyword_v2",
"tokenFilters":["lowercase", "front_edgeNGram"]
},
{
"@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"name":"ngram_back_analyzer",
"charFilters":[],
"tokenizer":"keyword_v2",
"tokenFilters":["lowercase", "back_edgeNGram"]
}
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": [
{
"@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
"name":"front_edgeNGram",
"minGram": 2,
"maxGram": 25,
"side": "front"
},
{
"@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
"name":"back_edgeNGram",
"minGram": 2,
"maxGram": 25,
"side": "back"
}
]
}
Для поиска номеров учетных записей, начинающихся с 123
, можно использовать следующий запрос:
{
"search": "123",
"searchFields": "accountNumber_prefix"
}
Чтобы найти номера учетных записей, которые заканчиваются 456
, можно использовать следующий запрос:
{
"search": "456",
"searchFields": "accountNumber_suffix"
}
Следующие шаги
В этой статье объясняется, как анализаторы создают и решают проблемы, связанные с запросами. В качестве следующего шага ознакомьтесь с анализаторами, влияющими на индексирование и обработку запросов.