Compartir vía


Indexación de blobs y archivos Markdown en Búsqueda de Azure AI

Nota:

Esta característica actualmente está en su versión preliminar pública. Esta versión preliminar se ofrece sin contrato de nivel de servicio y no es aconsejable usarla para cargas de trabajo de producción. Es posible que algunas características no sean compatibles o que tengan sus funcionalidades limitadas. Para más información, consulte Términos de uso complementarios de las Versiones Preliminares de Microsoft Azure.

En Búsqueda de Azure AI, los indexadores para Azure Blob Storage, Azure Files y OneLake admiten un modo de análisis de markdown para archivos Markdown. Los archivos Markdown se pueden indexar de dos maneras:

  • Modo de análisis de uno a varios, creando varios documentos de búsqueda por archivo Markdown
  • Modo de análisis de uno a uno, creando un documento de búsqueda por archivo Markdown

Sugerencia

Continúe con el Tutorial: Búsqueda de datos de Markdown desde Azure Blob Storage después de revisar este artículo.

Requisitos previos

  • Un origen de datos compatible: Azure Blob Storage, Azure File Storage, OneLake en Microsoft Fabric.

    En el caso de OneLake, asegúrese de cumplir todos los requisitos del indexador de OneLake.

    Azure Storage para indexadores de blobs y indexadores de archivos es una instancia estándar de rendimiento (uso general v2) que admite niveles de acceso frecuente y esporádico.

Parámetros del modo de análisis de Markdown

Los parámetros del modo de análisis se especifican en una definición del indexador al crear o actualizar un indexador.

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

El indexador de blobs proporciona un parámetro submode para determinar la salida de la estructura de los documentos de búsqueda. El modo de análisis de Markdown proporciona las siguientes opciones de submodo:

parsingMode submodo Buscar documento Descripción
markdown oneToMany Varios por blob (valor predeterminado) Divide el Markdown en varios documentos de búsqueda, cada uno de los cuales representa una sección de contenido (sin encabezado) del archivo Markdown. Puede omitir el submodo a menos que desee un análisis de uno a uno.
markdown oneToOne Uno por blob Analiza el Markdown en un documento de búsqueda, con secciones asignadas a encabezados específicos en el archivo Markdown.

En el caso del submodo oneToMany, debe examinar Indexación de blobs para producir varios documentos de búsqueda para conocer la forma en que el indexador de blobs controla la desambiguación de la clave del documento para varios documentos de búsqueda generados a partir del mismo blob.

En las secciones posteriores se describe cada submodo con más detalle. Si no está familiarizado con los conceptos y los clientes de indexador, consulte Creación de un indexador de búsqueda. También debe conocer los detalles de la configuración básica del indexador de blobs, que no se repite aquí.

Parámetros de análisis opcionales de Markdown

Los parámetros distinguen mayúsculas de minúsculas.

Nombre del parámetro Valores permitidos Descripción
markdownHeaderDepth h1, h2, h3, h4, h5, h6(default) Este parámetro determina el nivel de encabezado más profundo que se considera al analizar, lo que permite un control flexible de la estructura del documento (por ejemplo, cuando markdownHeaderDepth se establece en h1, el analizador solo reconoce encabezados de nivel superior que comienzan por "#" y todos los encabezados de nivel inferior se tratan como texto sin formato). Si no se especifica, el valor predeterminado es h6.

Esta configuración se puede cambiar después de la creación inicial del indexador, pero la estructura de los documentos de búsqueda resultantes podría cambiar en función del contenido Markdown.

Elementos Markdown compatibles

El análisis de Markdown solo dividirá el contenido en función de los encabezados. Todos los demás elementos, como listas, bloques de código, tablas, etc., se tratan como texto sin formato y se pasan a un campo de contenido.

Contenido Markdown de ejemplo

El siguiente contenido Markdown se usa para los ejemplos de esta página:

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Uso del modo de análisis de uno a varios

El modo de análisis de uno a varios analiza los archivos Markdown en varios documentos de búsqueda, donde cada documento corresponde a una sección de contenido específica del archivo Markdown en función de los metadatos de encabezado en ese punto del documento. El Markdown se analiza en función de los encabezados en documentos de búsqueda que contienen el siguiente contenido:

  • content: una cadena que contiene Markdown sin procesar que se encuentra en una ubicación específica, en función de los metadatos de encabezado en ese punto del documento.

  • sections: un objeto que contiene subcampos para los metadatos de encabezado hasta el nivel de encabezado deseado. Por ejemplo, cuando markdownHeaderDepth se establece en h3, contiene campos de cadena h1, h2 y h3. Estos campos se indexan mediante la creación de reflejo de esta estructura en el índice o mediante asignaciones de campos con el formato /sections/h1, sections/h2, etc. Consulte las configuraciones de índice e indexador en los siguientes ejemplos para obtener ejemplos en contexto. Los subcampos incluidos son:

    • h1: una cadena que contiene el valor del encabezado h1. Cadena vacía si no se ha establecido en este punto del documento.
    • (Opcional) h2: una cadena que contiene el valor del encabezado h2. Cadena vacía si no se ha establecido en este punto del documento.
    • (Opcional) h3: una cadena que contiene el valor del encabezado h3. Cadena vacía si no se ha establecido en este punto del documento.
    • (Opcional) h4: una cadena que contiene el valor del encabezado h4. Cadena vacía si no se ha establecido en este punto del documento.
    • (Opcional) h5: una cadena que contiene el valor del encabezado h5. Cadena vacía si no se ha establecido en este punto del documento.
    • (Opcional) h6: una cadena que contiene el valor del encabezado h6. Cadena vacía si no se ha establecido en este punto del documento.
  • ordinal_position: un valor entero que indica la posición de la sección dentro de la jerarquía de documentos. Este campo se usa para ordenar las secciones de su secuencia original tal como aparecen en el documento, empezando por una posición ordinal de 1 e incrementando secuencialmente para cada encabezado.

Esquema de índice para el análisis de uno a varios

Un ejemplo de configuración de un índice podría ser el siguiente:

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

Definición del indexador para el análisis de uno a varios

Si los nombres de campo y los tipos de datos coinciden, el indexador de blobs puede deducir la asignación sin que haya una asignación de campos explícita en la solicitud, por lo que una configuración del indexador correspondiente a la configuración de índice proporcionada podría tener este aspecto:

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

Nota:

No es necesario establecer explícitamente el submode porque oneToMany es el valor predeterminado.

Salida del indexador para el análisis de uno a varios

Este archivo Markdown daría como resultado tres documentos de búsqueda después de la indexación, debido a las tres secciones de contenido. El documento de búsqueda resultante de la primera sección de contenido del documento Markdown proporcionado contendrá los siguientes valores para content, sections, h1 y 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
  }
}   

Asignación de campos de uno a varios en un índice de búsqueda

Las asignaciones de campos asocian un campo de origen a un campo de destino en aquellas situaciones en las que los nombres de campo y los tipos no son idénticos. Pero las asignaciones de campo también se pueden usar para hacer coincidir partes de un documento Markdown y "elevarlas" a campos de nivel superior del documento de búsqueda.

En el siguiente ejemplo se muestra este escenario. Para obtener información sobre las asignaciones de campos, en general, consulte el artículo sobre asignaciones de campos.

Supongamos que tiene un índice de búsqueda con los siguientes campos: raw_content del tipo Edm.String, h1_header del tipo Edm.String y h2_header del tipo Edm.String. Para asignar Markdown en la forma deseada, utilice las siguientes asignaciones de campo:

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

El documento de búsqueda resultante en el índice tendría el siguiente aspecto:

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

Uso del modo de análisis de uno a uno

En el modo de análisis de uno a uno, todo el documento Markdown se indexa como un único documento de búsqueda, conservando la jerarquía y la estructura del contenido original. Este modo es más útil cuando los archivos que se van a indexar comparten una estructura común, de modo que se puede usar esta estructura común en el índice para que los campos pertinentes se puedan buscar.

En la definición del indexador, establezca el parsingMode en "markdown" y use el parámetro opcional markdownHeaderDepth para definir la profundidad máxima del encabezado para la fragmentación. Si no se especifica, el valor predeterminado es h6, capturando todas las profundidades de encabezado posibles.

El Markdown se analiza en función de los encabezados en documentos de búsqueda que contienen el siguiente contenido:

  • document_content: contiene el texto Markdown completo como una sola cadena. Este campo actúa como una representación sin procesar del documento de entrada.

  • sections: una matriz de objetos que contiene la representación jerárquica de las secciones del documento Markdown. Cada sección se representa como un objeto dentro de esta matriz y captura la estructura del documento de forma anidada correspondiendo a los encabezados y su respectivo contenido. Los campos son accesibles a través de asignaciones de campos haciendo referencia a la ruta de acceso, por ejemplo, /sections/content. Los objetos de esta matriz tienen las siguientes propiedades:

    • header_level: una cadena que indica el nivel del encabezado (h1, h2, h3, etc.) en la sintaxis Markdown. Este campo ayuda a comprender la jerarquía y la estructuración del contenido.

    • header_name: una cadena que contiene el texto del encabezado tal como aparece en el documento Markdown. Este campo proporciona una etiqueta o un título para la sección.

    • content: una cadena que contiene contenido de texto que sigue inmediatamente al encabezado, hasta el siguiente encabezado. Este campo captura la información detallada o la descripción asociada al encabezado. Si no hay contenido directamente bajo un encabezado, se trata de una cadena vacía.

    • ordinal_position: un valor entero que indica la posición de la sección dentro de la jerarquía de documentos. Este campo se usa para ordenar las secciones de su secuencia original tal como aparecen en el documento, empezando por una posición ordinal de 1 e incrementando secuencialmente para cada bloque de contenido.

    • sections: una matriz que contiene objetos que representan subsecciones anidadas en la sección actual. Esta matriz sigue la misma estructura que la matriz sections de nivel superior, lo que permite la representación de varios niveles de contenido anidado. Cada objeto de subsección también incluye propiedades header_level, header_name, content y ordinal_position, lo que permite una estructura recursiva que representa y jerarquiza el contenido Markdown.

Este es el ejemplo de Markdown que estamos usando para explicar un esquema de índice diseñado en torno a cada modo de análisis.

# Section 1
Content for section 1.

## Subsection 1.1
Content for subsection 1.1.

# Section 2
Content for section 2.

Esquema de índice para el análisis de uno a uno

Si no usa asignaciones de campos, la forma del índice debe reflejar la forma del contenido Markdown. Dada la estructura de Markdown de ejemplo con sus dos secciones y una sola subsección, el índice debe ser similar al ejemplo siguiente:

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

Definición del indexador para el análisis de uno a uno

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

Salida del indexador para el análisis de uno a uno

Dado que el Markdown que queremos indexar solo llega hasta una profundidad de h2 ("##"), necesitamos sections campos anidados a una profundidad de 2 para que coincida. Esta configuración daría lugar a los siguientes datos en el índice:

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

Como puede ver, la posición ordinal se incrementa en función de la ubicación del contenido del documento.

También debe tenerse en cuenta que si se omiten los niveles de encabezado en el contenido, entonces la estructura del documento resultante refleja los encabezados que están presentes en el contenido Markdown, no necesariamente contienen secciones anidadas para h1 a través de h6 de forma consecutiva. Por ejemplo, si el documento comienza en h2, el primer elemento de la matriz de secciones de nivel superior es h2.

Asignación de campos de uno a uno en un índice de búsqueda

Si desea extraer campos con nombres personalizados del documento, puede usar asignaciones de campos para hacerlo. Con el mismo ejemplo de Markdown que antes, tenga en cuenta la siguiente configuración de índice:

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

La extracción de campos específicos del Markdown analizado se realiza de forma similar a como se hace con las rutas del documento en outputFieldMappings, excepto que la ruta de acceso empieza por /sections en lugar de por /document. Por lo tanto, por ejemplo, /sections/0/content se asignaría al contenido debajo del elemento en la posición 0 de la matriz de secciones.

Un ejemplo de caso de uso potente podría ser algo así: todos los archivos Markdown tienen un título de documento en el primer h1, un título de subsección en el primer h2, y un resumen en el contenido del párrafo final debajo del h1 final. Puede usar las siguientes asignaciones de campos para indexar solo ese contenido:

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

Aquí extraería solo las partes pertinentes de ese documento. Para usar esta funcionalidad de forma más eficaz, los documentos que planea indexar deben compartir la misma estructura de encabezado jerárquica.

El documento de búsqueda resultante en el índice tendría el siguiente aspecto:

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

Nota:

Estos ejemplos especifican cómo usar estos modos de análisis completamente con o sin asignaciones de campos, pero puede aprovechar ambos en un escenario si se adapta a sus necesidades.

Pasos siguientes