Анализаторы для обработки текста в поиске ИИ Azure

Анализатор — это компонент системы полнотекстового поиска, отвечающий за обработку строк во время индексации и выполнения запроса. Обработка текста (также называемая лексическим анализом) преобразует строку запроса с помощью следующих действий:

  • Удаление слов, которые не представляют смысла (стоп-слова), и знаков пунктуации.
  • Разбиение фраз и слов с дефисом на части.
  • Преобразование слов в верхнем регистре в слова в нижнем регистре.
  • Сокращение слов до примитивных корневых форм, чтобы обеспечить эффективность хранения и возможность поиска совпадений независимо от грамматических форм.

Анализ применяется к полям Edm.String, которые помечены как "доступные для поиска", что означает полнотекстовый поиск.

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

Типы запросов, не имеющие полнотекстового поиска, такие как фильтры или нечеткий поиск, не проходят этап анализа на стороне запроса. Вместо этого средство синтаксического анализа отправляет эти строки непосредственно в поисковую систему, используя шаблон, который вы предоставляете в качестве основания для сопоставления. Как правило, для сопоставления шаблонов в этих формах запросов требуются маркеры целой строки. Чтобы обеспечить сохранение всех маркеров терминов во время индексирования, может потребоваться пользовательские анализаторы. Дополнительные сведения о том, когда и почему термины запросов анализируются, см. в полнотекстовом поиске в службе "Поиск ИИ Azure".

Чтобы получить дополнительные сведения о лексическом анализе, прослушайте следующий видеоролик с кратким объяснением.

Анализатор по умолчанию

В поиске ИИ Azure анализатор автоматически вызывается во всех строковых полях, помеченных как доступные для поиска.

По умолчанию поиск ИИ Azure использует анализатор Apache Lucene Standard (standard lucene), который разбивает текст на элементы после правил сегментации текста Юникода. Стандартный анализатор преобразует все знаки в нижний регистр. Анализу подвергаются как индексируемые документы, так и условия поиска во время индексирования и обработки запросов.

Можно переопределить значение по умолчанию для каждого поля. Альтернативными анализаторами могут быть языковые анализаторы для лингвистической обработки, пользовательские анализаторы или встроенные анализаторы, приведенные в списке доступных анализаторов.

Типы анализаторов

В следующем списке описывается, какие анализаторы доступны в службе "Поиск ИИ Azure".

Категория Description
Стандартный анализатор Lucene По умолчанию. Не требуется спецификация или настройка. Этот универсальный анализатор подходит для многих языков и сценариев.
Встроенные анализаторы Используются "как есть" и указываются по имени. Существует два типа: языковые и независимые от языка.

Специализированные анализаторы (независящие от языка) используются для текстовых входных данных, требующих специализированной или минимальной обработки. К примерам анализаторов в этой категории относятся Asciifolding, Keyword, Pattern, Simple, Stop, Whitespace.

Анализаторы языка используются, когда требуется расширенная лингвистическая поддержка отдельных языков. Поиск ИИ Azure поддерживает 35 анализаторов языка Lucene и 50 анализаторов обработки естественного языка Майкрософт.
Пользовательские анализаторы Относится к определенной пользователем конфигурации сочетания имеющихся элементов, которая состоит из одного лексического анализатора (обязательно) и необязательных фильтров (char или маркеров).

Несколько встроенных анализаторов, таких как Pattern или Stop, поддерживают ограниченный набор параметров. Чтобы задать эти параметры, необходимо создать пользовательский анализатор, состоящий из встроенного анализатора и одного из альтернативных вариантов, описанных в разделе Встроенные анализаторы. Как и в случае любой другой пользовательской настройки, присвойте новой конфигурации имя, например myPatternAnalyzer, чтобы отличать ее от анализатора Pattern Lucene.

Указание анализаторов

Настройка анализатора является необязательной. Как правило, можно использовать стандартный анализатор Lucene по умолчанию, чтобы узнать, как он работает. Если запросы не возвращают ожидаемые результаты, можно выбрать другой анализатор.

  1. Если вы используете пользовательский анализатор, добавьте его в индекс поиска в разделе "анализатор". Дополнительные сведения см. в статьях о создании индекса и пользовательских анализаторов.

  2. При определении поля задайте для свойства "анализатор" одно из следующих значений: встроенный анализатор, например ключевое слово, анализатор языка, например en.microsoft, или пользовательский анализатор (определенный в той же схеме индекса).

      "fields": [
     {
       "name": "Description",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": "en.microsoft",
       "indexAnalyzer": null,
       "searchAnalyzer": null
     },
    
  3. Если вы используете анализатор языка, необходимо использовать свойство "анализатор", чтобы указать его. Свойства searchAnalyzer и IndexAnalyzer не применяются к анализаторам языка.

  4. Кроме того, можно задать "indexAnalyzer" и "searchAnalyzer", чтобы разделить анализаторы для каждой рабочей нагрузки. Эти свойства работают вместе в качестве замены свойства "анализатора", которое должно иметь значение NULL. Для индексирования и запросов можно использовать различные анализаторы, если одно из этих действий требует определенного преобразования, которое не требуется другому.

      "fields": [
     {
       "name": "ProductGroup",
       "type": "Edm.String",
       "retrievable": true,
       "searchable": true,
       "analyzer": null,
       "indexAnalyzer": "keyword",
       "searchAnalyzer": "standard"
     },
    

Добавление анализаторов

Добавлять и назначать анализаторы лучше всего во время активной разработки, когда часто выполняется удаление и воссоздание индексов.

Поскольку анализаторы используются для маркировки терминов, следует назначить анализатор при создании поля. На самом деле назначение анализатора или indexAnalyzer полем, которое уже создано физически, не допускается (хотя свойство searchAnalyzer можно изменить в любое время без влияния на индекс).

Чтобы изменить анализатор существующего поля, необходимо удалить и повторно создать весь индекс (вы не можете перестроить отдельные поля). Для индексов в рабочей среде перестроение можно отложить, создав другое поле с новым назначением анализатора, и начать использовать его. Для внедрения нового поля используется запрос Update Index, а запрос mergeOrUpload позволяет заполнить его. Позже в рамках планового обслуживания индекса можно очистить его, чтобы удалить устаревшие поля.

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

Чтобы добавить пользовательский анализатор в существующий индекс, передайте флаг allowIndexDowntime в Update Index, если хотите избежать следующей ошибки:

"Index update not allowed because it would cause downtime. In order to add new analyzers, tokenizers, token filters, or character filters to an existing index, set the 'allowIndexDowntime' query parameter to 'true' in the index update request. Note that this operation will put your index offline for at least a few seconds, causing your indexing and query requests to fail. Performance and write availability of the index can be impaired for several minutes after the index is updated, or longer for very large indexes."

Рекомендации по работе с анализаторами

В этом разделе даны рекомендации по работе с анализаторами.

Использование одного анализатора для чтения и записи при отсутствии особых требований

Поиск ИИ Azure позволяет указать различные анализаторы для индексирования и поиска с помощью свойств поля IndexAnalyzer и searchAnalyzer. Если их не указать, анализатор с заданным свойством analyzer будет использоваться для двух операций — индексирования и поиска. Если не указать анализатор, будет использоваться стандартный анализатор Lucene.

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

Тестирование во время активной разработки

Переопределение стандартного анализатора требует перестроения индекса. Если это возможно, перед обработкой индекса в рабочей среде решите, для какого анализатора его использовать во время активной разработки.

Изучение терминов, снабженных маркером

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

Примеры REST

В примерах ниже приведены определения анализатора для нескольких ключевых сценариев.

Пример пользовательского анализатора

В этом примере демонстрируется определение анализатора с настраиваемыми параметрами. Настраиваемые параметры для фильтров типа char, лексических анализаторов и фильтров маркеров указываются отдельно как именованные конструкции, а затем в определении анализатора на них приводятся ссылки. Стандартные элементы используются как есть, и сослаться на них можно по имени.

Вот описание этого примера:

  • Анализаторы являются свойством класса поля для поля, поддерживающего поиск.

  • Пользовательский анализатор входит в определение индекса. Он может быть незначительно настроенным (например, настройка одного параметра в одном фильтре) или настроенным в нескольких местах.

  • В таком случае пользовательский анализатор "my_analyzer" в свою очередь использует настроенный стандартный лексический анализатор "my_standard_tokenizer" и два фильтра маркеров: с нижним регистром и настроенный фильтр типа asciifolding — "my_asciifolding".

  • Он также определяет 2 пользовательских фильтра char: "map_dash" и "remove_whitespace". Первый заменяет все тире символом подчеркивания, в то время как второй удаляет все пробелы. В соответствии с правилами сопоставления, все пробелы должны быть закодированы в формате UTF-8. Фильтры символов применяются перед разметкой и будут влиять на полученные маркеры (стандартная разметка делится на тире и пробелы, но не на подчеркивания).

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"my_analyzer"
        }
     ],
     "analyzers":[
        {
           "name":"my_analyzer",
           "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
           "charFilters":[
              "map_dash",
              "remove_whitespace"
           ],
           "tokenizer":"my_standard_tokenizer",
           "tokenFilters":[
              "my_asciifolding",
              "lowercase"
           ]
        }
     ],
     "charFilters":[
        {
           "name":"map_dash",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["-=>_"]
        },
        {
           "name":"remove_whitespace",
           "@odata.type":"#Microsoft.Azure.Search.MappingCharFilter",
           "mappings":["\\u0020=>"]
        }
     ],
     "tokenizers":[
        {
           "name":"my_standard_tokenizer",
           "@odata.type":"#Microsoft.Azure.Search.StandardTokenizerV2",
           "maxTokenLength":20
        }
     ],
     "tokenFilters":[
        {
           "name":"my_asciifolding",
           "@odata.type":"#Microsoft.Azure.Search.AsciiFoldingTokenFilter",
           "preserveOriginal":true
        }
     ]
  }

Пример назначения анализатора для каждого поля

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

Элемент "analyzer" переопределяет стандартный анализатор для каждого поля. Масштабное переопределение отсутствует. В этом примере text1 использует анализатор шаблона, а значение text2, которое не указывает анализатор, использует значение по умолчанию.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text1",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"pattern"
        },
        {
           "name":"text2",
           "type":"Edm.String",
           "searchable":true
        }
     ]
  }

Совмещение анализаторов для индексирования и поиска

API включает атрибуты индекса для указания других анализаторов для индексирования и поиска. Атрибуты searchAnalyzer и indexAnalyzer нужно указывать в сочетании, заменив отдельный атрибут analyzer.

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
     ],
  }

Пример анализатора языка

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

  {
     "name":"myindex",
     "fields":[
        {
           "name":"id",
           "type":"Edm.String",
           "key":true,
           "searchable":false
        },
        {
           "name":"text",
           "type":"Edm.String",
           "searchable":true,
           "indexAnalyzer":"whitespace",
           "searchAnalyzer":"simple"
        },
        {
           "name":"text_fr",
           "type":"Edm.String",
           "searchable":true,
           "analyzer":"fr.lucene"
        }
     ],
  }

Примеры C#

Если вы используете примеры кода пакета SDK для .NET, можно добавить эти примеры для использования или настройки анализаторов.

Назначение анализатора языка

Любой анализатор, используемый "как есть", без конфигурации, указывается в определении поля. Нет необходимости в создании записи в разделе [analyzers] индекса.

Языковые анализаторы используются как есть. Чтобы использовать их, вызовите LexicalAnalyzer, указав тип LexicalAnalyzerName, предоставляющий текстовый анализатор, поддерживаемый в поиске ИИ Azure.

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

    public partial class Hotel
    {
       . . . 
        [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnLucene)]
        public string Description { get; set; }

        [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)]
        [JsonPropertyName("Description_fr")]
        public string DescriptionFr { get; set; }

        [SearchableField(AnalyzerName = "url-analyze")]
        public string Url { get; set; }
      . . .
    }

Определение пользовательского анализатора

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

Создайте объект CustomAnalyzer. Пользовательский анализатор — это определяемое пользователем сочетание известного создателя маркеров, нуля или более фильтров маркеров и нуля или более имен символьных фильтров:

В следующем примере создается пользовательский анализатор с именем "url-analyze", использующий создатель маркеров uax_url_email и Фильтр маркеров нижнего регистра.

private static void CreateIndex(string indexName, SearchIndexClient adminClient)
{
   FieldBuilder fieldBuilder = new FieldBuilder();
   var searchFields = fieldBuilder.Build(typeof(Hotel));

   var analyzer = new CustomAnalyzer("url-analyze", "uax_url_email")
   {
         TokenFilters = { TokenFilterName.Lowercase }
   };

   var definition = new SearchIndex(indexName, searchFields);

   definition.Analyzers.Add(analyzer);

   adminClient.CreateOrUpdateIndex(definition);
}

Следующие шаги

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

Дополнительные сведения об анализаторах см. в следующих статьях: