Поделиться через


Индексирование BLOB-объектов Markdown и файлов в поиске искусственного интеллекта Azure

Примечание.

Эта функция сейчас доступна в виде общедоступной предварительной версии. Эта предварительная версия предоставляется без соглашения на уровне обслуживания и не рекомендуется для рабочих нагрузок. Некоторые функции могут не поддерживаться или их возможности могут быть ограничены. Дополнительные сведения см. в статье Дополнительные условия использования Предварительных версий Microsoft Azure.

В службе поиска ИИ Azure индексаторы для Хранилище BLOB-объектов Azure, Файлы Azure и OneLake поддерживают markdown режим синтаксического анализа для файлов Markdown. Файлы Markdown можно индексировать двумя способами:

  • Режим синтаксического анализа "один ко многим", создание нескольких документов поиска на файл Markdown
  • Режим синтаксического анализа один к одному, создание одного документа поиска на файл Markdown

Совет

Перейдите к руководству. Поиск данных Markdown из Хранилище BLOB-объектов Azure после просмотра этой статьи.

Необходимые компоненты

  • Поддерживаемый источник данных: хранилище BLOB-объектов Azure, хранилище файлов Azure, OneLake в Microsoft Fabric.

    Для OneLake убедитесь, что выполнены все требования индексатора OneLake.

    служба хранилища Azure для индексаторов BLOB-объектов и индексаторов файлов — это стандартный экземпляр производительности (версия 2 общего назначения), поддерживающий уровни горячего и холодного доступа.

Параметры режима синтаксического анализа Markdown

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

POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": {
      "parsingMode": "markdown",
      "markdownParsingSubmode": "oneToMany",
      "markdownHeaderDepth": "h6"
    }
  },
}

Индексатор BLOB-объектов предоставляет submode параметр для определения выходных данных структуры документов поиска. Режим синтаксического анализа Markdown предоставляет следующие параметры подмоде:

parsingMode подмоде Поиск документа Description
markdown oneToMany Несколько на большой двоичный объект (по умолчанию) Разбивает Markdown на несколько документов поиска, каждый из которых представляет раздел содержимого (негодер) файла Markdown. Вы можете опустить подмодеды, если вы не хотите выполнять синтаксический анализ по одному.
markdown oneToOne Один на большой двоичный объект Анализирует Markdown в один документ поиска с разделами, сопоставленными с определенными заголовками в файле Markdown.

Для oneToMany подмоде необходимо просмотреть индексирование одного большого двоичного объекта, чтобы создать множество документов поиска, чтобы понять, как индексатор BLOB-объектов обрабатывает диамбигуацию ключа документа для нескольких документов поиска, созданных из одного большого двоичного объекта.

В последующих разделах подробно описаны все подмодежи. Если вы не знакомы с клиентами и понятиями индексатора, см. статью "Создание индексатора поиска". Кроме того, следует ознакомиться с подробными сведениями о базовой конфигурации индексатора BLOB-объектов, которая здесь не приводится.

Необязательные параметры синтаксического анализа Markdown

Параметры зависят от регистра.

Наименование параметра Допустимые значения Description
markdownHeaderDepth h1, , h2h4h3h5,h6(default) Этот параметр определяет самый глубокий уровень заголовка, который учитывается при анализе, что позволяет гибко обрабатывать структуру документов (например, если markdownHeaderDepth задано h1значение , средство синтаксического анализа распознает только заголовки верхнего уровня, начинающиеся с "#", и все заголовки нижнего уровня рассматриваются как обычный текст). Если это значение не указано, по умолчанию используется h6.

Этот параметр можно изменить после первоначального создания индексатора, однако структура итоговых документов поиска может измениться в зависимости от содержимого Markdown.

Поддерживаемые элементы Markdown

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

Пример содержимого Markdown

Для примеров на этой странице используется следующее содержимое Markdown:

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Использование режима синтаксического анализа "один ко многим"

Режим синтаксического анализа "один ко многим" анализирует файлы Markdown в несколько документов поиска, где каждый документ соответствует определенному разделу содержимого файла Markdown на основе метаданных заголовка в этом документе. Markdown анализируется на основе заголовков в документы поиска, содержащие следующее содержимое:

  • content: строка, содержащая необработанный Markdown, найденный в определенном расположении, на основе метаданных заголовка в этом документе.

  • sections: объект, содержащий подфилды для метаданных заголовка до требуемого уровня заголовка. Например, если markdownHeaderDepth задано значение h3, содержит строковые поля h1и h2h3. Эти поля индексируются путем зеркального отображения этой структуры в индексе или путем сопоставления полей в формате /sections/h1, sections/h2и т. д. Сведения о конфигурациях индексатора и индексатора см. в следующих примерах. Вложенные поля:

    • h1 — Строка, содержащая значение заголовка h1. Пустая строка, если она не задана в данный момент в документе.
    • (Необязательно) h2— Строка, содержащая значение заголовка h2. Пустая строка, если она не задана в данный момент в документе.
    • (Необязательно) h3— Строка, содержащая значение заголовка h3. Пустая строка, если она не задана в данный момент в документе.
    • (Необязательно) h4— Строка, содержащая значение заголовка h4. Пустая строка, если она не задана в данный момент в документе.
    • (Необязательно) h5— Строка, содержащая значение заголовка h5. Пустая строка, если она не задана в данный момент в документе.
    • (Необязательно) h6— Строка, содержащая значение заголовка h6. Пустая строка, если она не задана в данный момент в документе.
  • ordinal_position: целочисленное значение, указывающее положение раздела в иерархии документов. Это поле используется для упорядочивания разделов в исходной последовательности, как они отображаются в документе, начиная с порядковой позиции 1 и последовательного увеличения для каждого заголовка.

Схема индекса для синтаксического анализа "один ко многим"

Пример конфигурации индекса может выглядеть примерно так:

{
  "name": "my-markdown-index",
  "fields": [
  {
    "name": "id",
    "type": "Edm.String",
    "key": true
  },
  {
    "name": "content",
    "type": "Edm.String",
  },
  {
    "name": "ordinal_position",
    "type": "Edm.Int32"
  },
  {
    "name": "sections",
    "type": "Edm.ComplexType",
    "fields": [
    {
      "name": "h1",
      "type": "Edm.String"
    },
    {
      "name": "h2",
      "type": "Edm.String"
    }]
  }]
}

Определение индексатора для синтаксического анализа "один ко многим"

Если имена полей и типы данных совпадают, индексатор BLOB-объектов может выводить сопоставление без явного сопоставления полей, присутствующих в запросе, поэтому конфигурация индексатора, соответствующая предоставленной конфигурации индекса, может выглядеть следующим образом:

POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": { "parsingMode": "markdown" }
  },
}

Примечание.

Не submode нужно явно задавать здесь, так как oneToMany используется значение по умолчанию.

Выходные данные индексатора для синтаксического анализа "один ко многим"

Этот файл Markdown приведет к трем документам поиска после индексирования из-за трех разделов содержимого. Документ поиска, полученный из первого раздела содержимого предоставленного документа Markdown, будет содержать следующие значения для content, sectionsh1иh2:

{
  {
    "content": "Content for section 1.\r\n",
    "sections": {
      "h1": "Section 1",
      "h2": ""
    },
    "ordinal_position": 1
  },
  {
    "content": "Content for subsection 1.1.\r\n",
    "sections": {
      "h1": "Section 1",
      "h2": "Subsection 1.1"
    },
    "ordinal_position": 2
  },
  {
    "content": "Content for section 2.\r\n",
    "sections": {
      "h1": "Section 2",
      "h2": ""
    },
    "ordinal_position": 3
  }
}   

Сопоставление полей "один ко многим" в индексе поиска

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

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

Допустим, что у вас есть индекс поиска со следующими полями: raw_content типа Edm.String, h1_header типа Edm.String и h2_header типа Edm.String. Чтобы сопоставить Markdown с нужной фигурой, используйте следующие сопоставления полей:

"fieldMappings" : [
    { "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
    { "sourceFieldName" : "/sections/h1", "targetFieldName" : "h1_header" },
    { "sourceFieldName" : "/sections/h2", "targetFieldName" : "h2_header" },
  ]

Результирующий документ поиска в индексе будет выглядеть следующим образом:

{
  {
    "raw_content": "Content for section 1.\r\n",
    "h1_header": "Section 1",
    "h2_header": "",
  },
  {
    "raw_content": "Content for section 1.1.\r\n",
    "h1_header": "Section 1",
    "h2_header": "Subsection 1.1",
  },
  {
    "raw_content": "Content for section 2.\r\n",
    "h1_header": "Section 2",
    "h2_header": "",
  }
}

Использование режима синтаксического анализа один к одному

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

В определении индексатора задайте parsingMode "markdown" и используйте необязательный markdownHeaderDepth параметр, чтобы определить максимальную глубину заголовка для фрагментирования. Если значение не указано, оно по умолчанию h6записывает все возможные глубины заголовков.

Markdown анализируется на основе заголовков в документы поиска, содержащие следующее содержимое:

  • document_content: содержит полный текст Markdown в виде одной строки. Это поле служит необработанным представлением входного документа.

  • sections: массив объектов, содержащих иерархическое представление разделов в документе Markdown. Каждый раздел представлен как объект в этом массиве и записывает структуру документа в вложенный способ, соответствующий заголовкам и их соответствующему содержимому. Поля доступны через сопоставления полей, ссылаясь на путь, например /sections/content. Объекты в этом массиве имеют следующие свойства:

    • header_level: строка, указывающая уровень заголовка (h1, h2, h3и т. д.) в синтаксисе Markdown. Это поле помогает понять иерархию и структурировать содержимое.

    • header_name: строка, содержащая текст заголовка, как она отображается в документе Markdown. Это поле предоставляет метку или заголовок для раздела.

    • content: строка, содержащая текстовое содержимое, которое сразу же следует за заголовком, вплоть до следующего заголовка. Это поле записывает подробные сведения или описание, связанные с заголовком. Если под заголовком нет содержимого, это пустая строка.

    • ordinal_position: целочисленное значение, указывающее положение раздела в иерархии документов. Это поле используется для упорядочивания разделов в исходной последовательности, как они отображаются в документе, начиная с порядковой позиции 1 и последовательного увеличения для каждого блока содержимого.

    • sections: массив, содержащий объекты, представляющие подразделы, вложенные в текущий раздел. Этот массив следует той же структуре, что и массив верхнего уровня sections , что позволяет представить несколько уровней вложенного содержимого. Каждый объект подраздела также включает header_level, contentheader_nameи ordinal_position свойства, позволяя рекурсивную структуру, представляющую и иерархию содержимого Markdown.

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

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Схема индекса для синтаксического анализа по одному

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

{
  "name": "my-markdown-index",
  "fields": [
  {
    "name": "document_content",
    "type": "Edm.String",
  {
    "name": "sections",
    "type": "Edm.ComplexType",
    "fields": [
    {
      "name": "header_level",
      "type": "Edm.String",
    },
    {
      "name": "header_name",
      "type": "Edm.String",
    },
    {
      "name": "content",
      "type": "Edm.String"
    },
    {
      "name": "ordinal_position",
      "type": "Edm.Int"
    },
    {
      "name": "sections",
      "type": "Edm.ComplexType",
      "fields": [
      {
        "name": "header_level",
        "type": "Edm.String",
      },
      {
        "name": "header_name",
        "type": "Edm.String",
      },
      {
        "name": "content",
        "type": "Edm.String"
      },
      {
        "name": "ordinal_position",
        "type": "Edm.Int"
      }]
    }]
  }
}

Определение индексатора для синтаксического анализа

POST https://[service name].search.windows.net/indexers?api-version=2024-11-01-preview
Content-Type: application/json
api-key: [admin key]

{
  "name": "my-markdown-indexer",
  "dataSourceName": "my-blob-datasource",
  "targetIndexName": "my-target-index",
  "parameters": {
    "configuration": {
      "parsingMode": "markdown",
      "markdownParsingSubmode": "oneToOne",
    }
  }
}

Выходные данные индексатора для синтаксического анализа

Так как Markdown мы хотим индексировать только глубину ("#"), нам нужноsections, чтобы поля вложены в глубину h2 2, чтобы сопоставить это. Эта конфигурация приведет к следующим данным в индексе:

  "document_content": "# Section 1\r\nContent for section 1.\r\n## Subsection 1.1\r\nContent for subsection 1.1.\r\n# Section 2\r\nContent for section 2.\r\n",
  "sections": [
    {
      "header_level": "h1",
      "header_name": "Section 1",
      "content": "Content for section 1.",
      "ordinal_position": 1,
      "sections": [
        {
          "header_level": "h2",
          "header_name": "Subsection 1.1",
          "content": "Content for subsection 1.1.",
          "ordinal_position": 2,
        }]
    }],
    {
      "header_level": "h1",
      "header_name": "Section 2",
      "content": "Content for section 2.",
      "ordinal_position": 3,
      "sections": []
    }]
  }

Как видно, порядковое положение увеличивается в зависимости от расположения содержимого в документе.

Также следует отметить, что если уровни заголовков пропускаются в содержимом, структура результирующего документа отражает заголовки, которые присутствуют в содержимом Markdown, а не обязательно содержат вложенные разделы для h1 последовательного выполнения h6 . Например, когда документ начинается h2с, то первый элемент в массиве разделов верхнего уровня .h2

Сопоставление полей "один к одному" в индексе поиска

Если вы хотите извлечь поля с пользовательскими именами из документа, можно использовать сопоставления полей для этого. Используя тот же пример Markdown, что и раньше, рассмотрим следующую конфигурацию индекса:

{
  "name": "my-markdown-index",
  "fields": [
    {
      "name": "document_content",
      "type": "Edm.String",
    },
    {
      "name": "document_title",
      "type": "Edm.String",
    },
    {
      "name": "opening_subsection_title"
      "type": "Edm.String",
    }
    {
      "name": "summary_content",
      "type": "Edm.String",
    }
  ]
}

Извлечение определенных полей из синтаксического Markdown обрабатывается аналогично тому, как пути к документу находятся в outputFieldMappings, за исключением того, что путь начинается вместо /sections /documentнего. Например, /sections/0/content будет сопоставляться с содержимым под элементом в позиции 0 в массиве разделов.

Пример строгого варианта использования может выглядеть примерно так: все файлы Markdown имеют заголовок документа в первом, заголовок подраздела в первом h1h2и сводку в содержимом окончательного абзаца под окончательнымh1. Для индексирования этого содержимого можно использовать следующие сопоставления полей:

"fieldMappings" : [
  { "sourceFieldName" : "/content", "targetFieldName" : "raw_content" },
  { "sourceFieldName" : "/sections/0/header_name", "targetFieldName" : "document_title" },
  { "sourceFieldName" : "/sections/0/sections/header_name", "targetFieldName" : "opening_subsection_title" },
  { "sourceFieldName" : "/sections/1/content", "targetFieldName" : "summary_content" },
]

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

Результирующий документ поиска в индексе будет выглядеть следующим образом:

{
  "content": "Content for section 1.\r\n",
  "document_title": "Section 1",
  "opening_subsection_title": "Subsection 1.1",
  "summary_content": "Content for section 2."
}

Примечание.

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

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