Partager via


Indexer des objets blob et des fichiers Markdown dans Recherche Azure AI

Remarque

Cette fonctionnalité est actuellement disponible en préversion publique. Cette préversion est fournie sans contrat de niveau de service et n’est pas recommandée pour les charges de travail de production. Certaines fonctionnalités peuvent être limitées ou non prises en charge. Pour plus d’informations, consultez Conditions d’Utilisation Supplémentaires relatives aux Évaluations Microsoft Azure.

Dans Recherche Azure AI, les indexeurs pour Stockage Blob Azure, Azure Files et OneLake prennent en charge un markdown mode d’analyse pour les fichiers Markdown. Les fichiers Markdown peuvent être indexés de deux façons :

  • Mode d’analyse un-à-plusieurs, création de plusieurs documents de recherche par fichier Markdown
  • Mode d’analyse un-à-un, création d’un document de recherche par fichier Markdown

Prérequis

  • Source de données prise en charge : Stockage Blob Azure, Stockage Fichier Azure, OneLake dans Microsoft Fabric.

    Pour OneLake, veillez à répondre à toutes les exigences de l’indexeur OneLake.

    Stockage Azure pour indexeurs d’objets blob et indexeurs de fichiers est une instance de performances standard (v2 à usage général) qui prend en charge les niveaux d’accès chaud, froid et froid.

Paramètres du mode d’analyse Markdown

Les paramètres du mode d’analyse sont spécifiés dans une définition d’indexeur lorsque vous créez ou mettez à jour un indexeur.

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"
    }
  },
}

L’indexeur d’objets blob fournit un paramètre submode pour déterminer la sortie de la structure des documents de recherche. Le mode d’analyse Markdown fournit les options de sous-modèle suivantes :

parsingMode sous-modèle Document de recherche Description
markdown oneToMany Plusieurs par objet blob (par défaut) Décompose Markdown en plusieurs documents de recherche, chacun représentant une section de contenu (non-header) du fichier Markdown. Vous pouvez omettre le sous-modèle, sauf si vous souhaitez analyser un-à-un.
markdown oneToOne Un seul par objet blob Analyse markdown dans un document de recherche, avec des sections mappées à des en-têtes spécifiques dans le fichier Markdown.

Pour oneToMany sous-modèle, vous devez consulter Indexer un objet blob pour produire de nombreux documents de recherche pour comprendre comment l’indexeur d’objets blob gère l’ambiguïté de la clé de document pour plusieurs documents de recherche produits à partir du même objet blob.

Les sections ultérieures décrivent chaque sous-modèle plus en détail. Si vous n’êtes pas familiarisé avec les clients et les concepts d’indexeur, consultez Créer un indexeur de recherche. Vous devez également connaître les détails de la configuration d’un indexeur d’objets blob simple, qui n’est pas reprise ici.

Paramètres d’analyse Markdown facultatifs

Les paramètres respectent la casse.

Nom du paramètre Valeurs autorisées Description
markdownHeaderDepth h1, h2, h3, h4, h5, h6(default) Ce paramètre détermine le niveau d’en-tête le plus profond qui est pris en compte lors de l’analyse, ce qui permet une gestion flexible de la structure de documents (par exemple, lorsque markdownHeaderDepth est défini sur h1, l’analyseur reconnaît uniquement les en-têtes de niveau supérieur commençant par « # », et tous les en-têtes de niveau inférieur sont traités comme du texte brut). S’il n’est pas spécifié, il est défini par défaut sur h6.

Ce paramètre peut être modifié après la création initiale de l’indexeur, mais la structure des documents de recherche résultants peut changer en fonction du contenu Markdown.

Éléments Markdown pris en charge

L’analyse Markdown fractionne uniquement le contenu en fonction des en-têtes. Tous les autres éléments tels que les listes, les blocs de code, les tables, etc., sont traités comme du texte brut et transmis dans un champ de contenu.

Exemple de contenu Markdown

Le contenu Markdown suivant est utilisé pour les exemples de cette page :

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Utiliser le mode d’analyse un-à-plusieurs

Le mode d’analyse un-à-plusieurs analyse les fichiers Markdown dans plusieurs documents de recherche, où chaque document correspond à une section de contenu spécifique du fichier Markdown en fonction des métadonnées d’en-tête à ce stade du document. Markdown est analysé en fonction des en-têtes dans des documents de recherche qui contiennent le contenu suivant :

  • content: chaîne qui contient le Markdown brut trouvé dans un emplacement spécifique, en fonction des métadonnées d’en-tête à ce stade du document.

  • sections : objet qui contient des sous-champs pour les métadonnées d’en-tête jusqu’au niveau d’en-tête souhaité. Par exemple, lorsque markdownHeaderDepth est défini sur h3, contient des champs de chaîne h1, h2et h3. Ces champs sont indexés en mettant en miroir cette structure dans l’index, ou via des mappages de champs au format /sections/h1, sections/h2, etc. Consultez les configurations d’index et d’indexeur dans les exemples suivants pour obtenir des exemples dans le contexte. Les sous-champs contenus sont les suivants :

    • h1 : chaîne contenant la valeur d’en-tête h1. Chaîne vide si elle n’est pas définie à ce stade dans le document.
    • (Facultatif) h2 : chaîne contenant la valeur d’en-tête h2. Chaîne vide si elle n’est pas définie à ce stade dans le document.
    • (Facultatif) h3 : chaîne contenant la valeur d’en-tête h3. Chaîne vide si elle n’est pas définie à ce stade dans le document.
    • (Facultatif) h4 : chaîne contenant la valeur d’en-tête h4. Chaîne vide si elle n’est pas définie à ce stade dans le document.
    • (Facultatif) h5 : chaîne contenant la valeur d’en-tête h5. Chaîne vide si elle n’est pas définie à ce stade dans le document.
    • (Facultatif) h6 : chaîne contenant la valeur d’en-tête h6. Chaîne vide si elle n’est pas définie à ce stade dans le document.
  • ordinal_position: valeur entière indiquant la position de la section dans la hiérarchie de documents. Ce champ est utilisé pour classer les sections dans leur séquence d’origine à mesure qu’elles apparaissent dans le document, en commençant par une position ordinale de 1 et en incrémentant séquentiellement pour chaque en-tête.

Schéma d’index pour l’analyse un-à-plusieurs

Un exemple de configuration d’index peut ressembler à ceci :

{
  "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"
    }]
  }]
}

Définition de l’indexeur pour l’analyse un-à-plusieurs

Si les noms de champs et les types de données s’alignent, l’indexeur d’objets blob peut déduire le mappage sans mappage de champ explicite présent dans la requête. Par conséquent, une configuration d’indexeur correspondant à la configuration d’index fournie peut ressembler à ceci :

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" }
  },
}

Remarque

La submode n’a pas besoin d’être définie explicitement ici, car oneToMany est la valeur par défaut.

Sortie de l’indexeur pour l’analyse un-à-plusieurs

Ce fichier Markdown entraînerait trois documents de recherche après l’indexation, en raison des trois sections de contenu. Le document de recherche résultant de la première section de contenu du document Markdown fourni contient les valeurs suivantes pour content, sections, h1et 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
  }
}   

Mapper des champs un-à-plusieurs dans un index de recherche

Les mappages de champs associent un champ source à un champ de destination dans les situations où les noms et types de champs ne sont pas identiques. Toutefois, les mappages de champs peuvent également être utilisés pour faire correspondre des parties d’un document Markdown et les « lift » dans des champs de niveau supérieur du document de recherche.

L’exemple suivant illustre ce scénario. Pour en savoir plus sur les mappages de champs en général, consultez Mappages de champs.

Prenons un index de recherche avec les champs suivants : raw_content de type Edm.String, h1_header de type Edm.String et h2_header de type Edm.String. Pour mapper votre Markdown à la forme souhaitée, utilisez les mappages de champs suivants :

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

Le document de recherche obtenu dans l’index se présente comme suit :

{
  {
    "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": "",
  }
}

Utiliser le mode d’analyse un-à-un

Dans le mode d’analyse un-à-un, l’intégralité du document Markdown est indexée en tant que document de recherche unique, conservant la hiérarchie et la structure du contenu d’origine. Ce mode est le plus utile lorsque les fichiers à indexer partagent une structure commune, afin que vous puissiez utiliser cette structure commune dans l’index pour rendre les champs pertinents pouvant faire l’objet d’une recherche.

Dans la définition de l’indexeur, définissez la parsingMode sur "markdown" et utilisez le paramètre facultatif markdownHeaderDepth pour définir la profondeur de titre maximale pour la segmentation. S’il n’est pas spécifié, il est par défaut h6, en capturant toutes les profondeurs d’en-tête possibles.

Markdown est analysé en fonction des en-têtes dans des documents de recherche qui contiennent le contenu suivant :

  • document_content: contient le texte Markdown complet sous forme de chaîne unique. Ce champ sert de représentation brute du document d’entrée.

  • sections: tableau d’objets qui contient la représentation hiérarchique des sections dans le document Markdown. Chaque section est représentée en tant qu’objet dans ce tableau et capture la structure du document de manière imbriquée correspondant aux en-têtes et à leur contenu respectif. Les champs sont accessibles via des mappages de champs en référençant le chemin d’accès, par exemple /sections/content. Les objets de ce tableau ont les propriétés suivantes :

    • header_level: chaîne qui indique le niveau de l’en-tête (h1, h2, h3, etc.) dans la syntaxe Markdown. Ce champ permet de comprendre la hiérarchie et la structure du contenu.

    • header_name: chaîne contenant le texte de l’en-tête tel qu’il apparaît dans le document Markdown. Ce champ fournit une étiquette ou un titre pour la section.

    • content: chaîne contenant du contenu texte qui suit immédiatement l’en-tête, jusqu’à l’en-tête suivant. Ce champ capture les informations détaillées ou la description associées à l’en-tête. S’il n’y a pas de contenu directement sous un en-tête, il s’agit d’une chaîne vide.

    • ordinal_position: valeur entière indiquant la position de la section dans la hiérarchie de documents. Ce champ est utilisé pour classer les sections dans leur séquence d’origine à mesure qu’ils apparaissent dans le document, en commençant par une position ordinale de 1 et en incrémentant séquentiellement pour chaque bloc de contenu.

    • sections: tableau qui contient des objets représentant des sous-sections imbriquées sous la section actuelle. Ce tableau suit la même structure que le tableau de niveau supérieur sections, ce qui permet la représentation de plusieurs niveaux de contenu imbriqué. Chaque objet de sous-section inclut également des propriétés header_level, header_name, contentet ordinal_position, ce qui permet une structure récursive qui représente et une hiérarchie du contenu Markdown.

Voici l’exemple Markdown que nous utilisons pour expliquer un schéma d’index conçu autour de chaque mode d’analyse.

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Schéma d’index pour l’analyse un-à-un

Si vous n’utilisez pas de mappages de champs, la forme de l’index doit refléter la forme du contenu Markdown. Étant donné la structure de l’exemple Markdown avec ses deux sections et sa sous-section unique, l’index doit ressembler à l’exemple suivant :

{
  "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"
      }]
    }]
  }
}

Définition de l’indexeur pour l’analyse un-à-un

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",
    }
  }
}

Sortie de l’indexeur pour l’analyse un-à-un

Étant donné que markdown que nous voulons indexer ne passe qu’à une profondeur de h2 (« ## »), nous devons sections champs imbriqués à une profondeur de 2 pour correspondre à cela. Cette configuration entraînerait les données suivantes dans l’index :

  "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": []
    }]
  }

Comme vous pouvez le voir, la position ordinale incrémente en fonction de l’emplacement du contenu dans le document.

Il convient également de noter que si les niveaux d’en-tête sont ignorés dans le contenu, la structure du document résultant reflète les en-têtes présents dans le contenu Markdown, qui ne contiennent pas nécessairement des sections imbriquées pour h1 via h6 consécutivement. Par exemple, lorsque le document commence à h2, le premier élément du tableau de sections de niveau supérieur est h2.

Mapper des champs un-à-un dans un index de recherche

Si vous souhaitez extraire des champs avec des noms personnalisés à partir du document, vous pouvez utiliser des mappages de champs pour ce faire. À l’aide du même exemple Markdown que précédemment, tenez compte de la configuration d’index suivante :

{
  "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",
    }
  ]
}

L’extraction de champs spécifiques de Markdown analysés est gérée de la même façon que les chemins d’accès au document se trouvent dans outputFieldMappings, sauf que le chemin commence par /sections au lieu de /document. Par exemple, /sections/0/contentmapperait le contenu sous l’élément à la position 0 dans le tableau de sections.

Un exemple de cas d’usage fort peut ressembler à ceci : tous les fichiers Markdown ont un titre de document dans la première h1, un titre de sous-section dans le premier h2et un résumé dans le contenu du paragraphe final sous le finalh1. Vous pouvez utiliser les mappages de champs suivants pour indexer uniquement ce contenu :

"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" },
]

Ici, vous n’extrairiez que les éléments pertinents de ce document. Pour utiliser efficacement cette fonctionnalité, les documents que vous prévoyez d’indexer doivent partager la même structure d’en-tête hiérarchique.

Le document de recherche obtenu dans l’index se présente comme suit :

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

Remarque

Ces exemples spécifient comment utiliser ces modes d’analyse entièrement avec ou sans mappages de champs, mais vous pouvez tirer parti des deux dans un scénario si cela convient à vos besoins.

Étapes suivantes