Compartir vía


Asignación de resultados enriquecidos a campos de un índice de búsqueda en Azure AI Search

Diagrama de las fases del indizador con asignaciones de campos de salida destacadas.

En este artículo se explica cómo configurar asignaciones de campos de salida, definiendo una ruta de acceso de datos entre datos en memoria generados durante procesamiento de conjuntos de aptitudes, y campos de destino en un índice de búsqueda. Durante la ejecución del indexador, la información generada por aptitudes solo existe en memoria. Para conservar esta información en un índice de búsqueda, debe indicar al indexador dónde enviar los datos.

Una asignación de campos de salida se define en un indizador y tiene los siguientes elementos:

"outputFieldMappings": [
  {
    "sourceFieldName": "document/path-to-a-node-in-an-enriched-document",
    "targetFieldName": "some-search-field-in-an-index",
    "mappingFunction": null
  }
],

A diferencia de una definición de fieldMappings que asigna una ruta de acceso entre los campos de origen textual y los campos de índice, una definición de outputFieldMappings asigna enriquecimientos en memoria a los campos de un índice de búsqueda.

Requisitos previos

  • Indexador, índice, origen de datos y conjunto de aptitudes.

  • Los campos de índice deben ser campos simples o de nivel superior. No se puede generar una salida a un tipo complejo. Sin embargo, si tiene un tipo complejo, puede usar una definición de campo de salida para aplanar partes del tipo complejo y enviarlos a una colección en un índice de búsqueda.

Cuándo usar una asignación de campos de salida

Las asignaciones de campos de salida son necesarias si el indexador tiene un conjunto de aptitudes asociado que crea información nueva que desea en el índice. Algunos ejemplos son:

  • Vectores de aptitudes de inserción
  • Aptitudes para el reconocimiento óptico de caracteres (OCR) de texto a partir de imágenes
  • Ubicaciones, organizaciones o personas de aptitudes de reconocimiento de entidades

Las asignaciones de campos de salida también se pueden usar para:

  • Cree varias copias del contenido generado (asignaciones de campos de salida de uno a varios).

  • Aplane el tipo complejo de un documento de origen. Por ejemplo, supongamos que los documentos de origen tienen un tipo complejo, como una dirección de varias partes, y solo quiere la ciudad. Puede usar una asignación de campos de salida para aplanar una estructura de datos anidada, y a continuación, usar una asignación de campo de salida para enviar la salida a una colección de cadenas en el índice de búsqueda.

Las asignaciones de campos de salida solo se aplican a índices de búsqueda. Si va a rellenar un almacén de conocimiento, use proyecciones para la configuración de la ruta de acceso de datos.

Definición de una asignación de campos de salida

Las asignaciones de campos de salida se agregan a la matriz outputFieldMappings en una definición de indexador, normalmente colocadas después de la matriz fieldMappings. Una asignación de campos consta de tres partes.

Puede usar el portal, la API de REST o un SDK de Azure para definir asignaciones de campos.

Sugerencia

Los indexadores creados por el Asistente para importación de datos incluyen asignaciones de campos de salida generadas por el asistente. Si necesita ejemplos, ejecute el asistente sobre el origen de datos para ver las asignaciones de campos de salida en el indexador.

  1. Use Crear índice o Crear o actualizar indexador o un método equivalente de un SDK de Azure. Este es un ejemplo de una definición de indexador.

    {
       "name": "myindexer",
       "description": null,
       "dataSourceName": "mydatasource",
       "targetIndexName": "myindex",
       "schedule": { },
       "parameters": { },
       "fieldMappings": [],
       "outputFieldMappings": [],
       "disabled": false,
       "encryptionKey": { }
     }
    
  2. Rellene la matriz outputFieldMappings para especificar las asignaciones. Una asignación de campos consta de tres partes.

    "outputFieldMappings": [
      {
        "sourceFieldName": "/document/path-to-a-node-in-an-enriched-document",
        "targetFieldName": "some-search-field-in-an-index",
        "mappingFunction": null
      }
    ]
    
    Propiedad Descripción
    sourceFieldName Necesario. Especifica una ruta de acceso al contenido enriquecido. Un ejemplo podría ser /document/content. Para ver ejemplos y la sintaxis de la ruta de acceso, consulte Enriquecimientos de referencia en un conjunto de aptitudes de Azure AI Search.
    targetFieldName Opcional. Especifica el campo de búsqueda que recibe el contenido enriquecido. Los campos de destino deben ser campos o colecciones simples de nivel superior. No puede ser una ruta de acceso a un subcampo en un tipo complejo. Si desea recuperar nodos específicos en una estructura compleja, puede acoplar nodos individuales en memoria y, a continuación, enviar la salida a una colección de cadenas en el índice.
    mappingFunction Opcional. Agrega procesamiento adicional proporcionado por las funciones de asignación compatibles con los indexadores. Para los nodos de enriquecimiento, la codificación y la descodificación son las funciones más usadas.
  3. El targetFieldName es siempre es el nombre del campo en el índice de búsqueda.

  4. El sourceFieldName es una ruta de acceso a un nodo del documento enriquecido. Es la salida de una aptitud. La ruta de acceso siempre empieza por /document, y si está indexando a partir de un blob, el segundo elemento de la ruta es /content. El tercer elemento es el valor generado por la aptitud. Para más información y ejemplos, vea Enriquecimientos de referencia en un conjunto de aptitudes de Azure AI Search.

    En este ejemplo se agregan entidades y etiquetas de opinión extraídas de la propiedad de contenido de un blob a los campos de un índice de búsqueda.

    {
        "name": "myIndexer",
        "dataSourceName": "myDataSource",
        "targetIndexName": "myIndex",
        "skillsetName": "myFirstSkillSet",
        "fieldMappings": [],
        "outputFieldMappings": [
            {
                "sourceFieldName": "/document/content/organizations/*/description",
                "targetFieldName": "descriptions",
                "mappingFunction": {
                    "name": "base64Decode"
                }
            },
            {
                "sourceFieldName": "/document/content/organizations",
                "targetFieldName": "orgNames"
            },
            {
                "sourceFieldName": "/document/content/sentiment",
                "targetFieldName": "sentiment"
            }
        ]
    }
    
  5. Asigne las funciones de asignación necesarias para transformar el contenido de un campo antes de almacenarlo en el índice. Para los nodos de enriquecimiento, la codificación y la descodificación son las funciones más usadas.

Asignación de campos de salida de uno a varios

Puede usar una asignación de campos de salida para enrutar un único campo de origen a varios campos de un índice de búsqueda. Puede hacerlo para realizar pruebas de comparación o si quiere campos con atributos diferentes.

Supongamos un conjunto de aptitudes que genera inserciones para un campo vectorial y un índice que tiene varios campos vectoriales que varían según la configuración de algoritmo y compresión. Dentro del indexador, asigne la salida de la aptitud de inserción a cada uno de los varios campos vectoriales de un índice de búsqueda.

"outputFieldMappings": [
    { "sourceFieldName" : "/document/content/text_vector", "targetFieldName" : "vector_hnsw" }, 
    { "sourceFieldName" : "/document/content/text_vector", "targetFieldName" : "vector_eknn" },
    { "sourceFieldName" : "/document/content/text_vector", "targetFieldName" : "vector_narrow" }, 
    { "sourceFieldName" : "/document/content/text_vector", "targetFieldName" : "vector_no_stored" },
    { "sourceFieldName" : "/document/content/text_vector", "targetFieldName" : "vector_scalar" }       
  ]

La ruta de acceso del campo de origen es la salida de la aptitud. En este ejemplo, la salida es text_vector. El nombre de destino es una propiedad opcional. Si no asigna un nombre de destino a la asignación de salida, la ruta sería embedding o, más exactamente, /document/content/embedding.

{
  "name": "test-vector-size-ss",  
  "description": "Generate embeddings using Azure OpenAI Service",
  "skills": [
    {
      "@odata.type": "#Microsoft.Skills.Text.AzureOpenAIEmbeddingSkill",
      "name": "#1",
      "description": null,
      "context": "/document/content",
      "resourceUri": "https://my-demo-eastus.openai.azure.com",
      "apiKey": null,
      "deploymentId": "text-embedding-ada-002",
      "dimensions": 1536,
      "modelName": "text-embedding-ada-002",
      "inputs": [
        {
          "name": "text",
          "source": "/document/content"
        }
      ],
      "outputs": [
        {
          "name": "embedding",
          "targetName": "text_vector"
        }
      ],
      "authIdentity": null
    }
  ]
}

Acoplar estructuras complejas en una colección de cadenas

Si los datos de origen se componen de JSON anidados o jerárquicos, no puede usar asignaciones de campos para configurar las rutas de acceso de datos. En su lugar, el índice de búsqueda debe reflejar la estructura de datos de origen para cada nivel para una importación completa.

Esta sección le guía a través de un proceso de importación que genera una reflexión uno a uno de un documento complejo en los lados de origen y destino. A continuación, usa el mismo documento de origen para ilustrar la recuperación y acoplamiento de nodos individuales en colecciones de cadenas.

Este es un ejemplo de un documento en Azure Cosmos DB con JSON anidado:

{
   "palette":"primary colors",
   "colors":[
      {
         "name":"blue",
         "medium":[
            "acrylic",
            "oil",
            "pastel"
         ]
      },
      {
         "name":"red",
         "medium":[
            "acrylic",
            "pastel",
            "watercolor"
         ]
      },
      {
         "name":"yellow",
         "medium":[
            "acrylic",
            "watercolor"
         ]
      }
   ]
}

Si quisiera indexar completamente este documento de origen, crearía una definición de índice en la que los nombres de campo, los niveles y los tipos se reflejan como un tipo complejo. Dado que las asignaciones de campos no se admiten para tipos complejos en el índice de búsqueda, la definición del índice debe reflejar el documento de origen.

{
  "name": "my-test-index",
  "defaultScoringProfile": "",
  "fields": [
    { "name": "id", "type": "Edm.String", "searchable": false, "retrievable": true, "key": true},
    { "name": "palette", "type": "Edm.String", "searchable": true, "retrievable": true },
    { "name": "colors", "type": "Collection(Edm.ComplexType)",
      "fields": [
        {
          "name": "name",
          "type": "Edm.String",
          "searchable": true,
          "retrievable": true
        },
        {
          "name": "medium",
          "type": "Collection(Edm.String)",
          "searchable": true,
          "retrievable": true,
        }
      ]
    }
  ]
}

Esta es una definición de indexador de ejemplo que ejecuta la importación. Observe que no hay asignaciones de campos ni conjuntos de aptitudes.

{
  "name": "my-test-indexer",
  "dataSourceName": "my-test-ds",
  "skillsetName": null,
  "targetIndexName": "my-test-index",

  "fieldMappings": [],
  "outputFieldMappings": []
}

El resultado es el siguiente documento de búsqueda de ejemplo, similar al original en Azure Cosmos DB.

{
  "value": [
    {
      "@search.score": 1,
      "id": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff",
      "palette": "primary colors",
      "colors": [
        {
          "name": "blue",
          "medium": [
            "acrylic",
            "oil",
            "pastel"
          ]
        },
        {
          "name": "red",
          "medium": [
            "acrylic",
            "pastel",
            "watercolor"
          ]
        },
        {
          "name": "yellow",
          "medium": [
            "acrylic",
            "watercolor"
          ]
        }
      ]
    }
  ]
}

Una representación alternativa en un índice de búsqueda consiste en acoplar nodos individuales en la estructura anidada del origen en una colección de cadenas en un índice de búsqueda.

Para realizar esta tarea, necesitará un outputFieldMappings que asigne un nodo en memoria a una colección de cadenas en el índice. Aunque las asignaciones de campos de salida se aplican principalmente a las salidas de aptitud, también puede usarlas para dirigir los nodos después de descifrado de documentos donde el indexador abre un documento de origen y lo lee en la memoria.

El siguiente ejemplo de definición de índices utiliza colecciones de cadenas para recibir la salida aplanada:

{
  "name": "my-new-flattened-index",
  "defaultScoringProfile": "",
  "fields": [
    { "name": "id", "type": "Edm.String", "searchable": false, "retrievable": true, "key": true },
    { "name": "palette", "type": "Edm.String", "searchable": true, "retrievable": true },
    { "name": "color_names", "type": "Collection(Edm.String)", "searchable": true, "retrievable": true },
    { "name": "color_mediums", "type": "Collection(Edm.String)", "searchable": true, "retrievable": true}
  ]
}

Esta es la definición del indexador de ejemplo, mediante outputFieldMappings para asociar el JSON anidado a los campos de colección de cadenas. Observe que el campo de origen usa la sintaxis de ruta de acceso para los nodos de enriquecimiento, aunque no haya ningún conjunto de aptitudes. Los documentos enriquecidos se crean en el sistema durante el descifrado de documentos, lo que significa que puede acceder a los nodos de cada árbol de documentos siempre que existan esos nodos cuando se descifra el documento.

{
  "name": "my-test-indexer",
  "dataSourceName": "my-test-ds",
  "skillsetName": null,
  "targetIndexName": "my-new-flattened-index",
  "parameters": {  },
  "fieldMappings": [   ],
  "outputFieldMappings": [
    {
       "sourceFieldName": "/document/colors/*/name",
       "targetFieldName": "color_names"
    },
    {
       "sourceFieldName": "/document/colors/*/medium",
       "targetFieldName": "color_mediums"
    }
  ]
}

Los resultados de la definición son los siguientes. Simplificar la estructura pierde el contexto en este caso. Ya no hay ninguna asociación entre un color determinado y los medios en los que está disponible. Sin embargo, dependiendo de su escenario, un resultado similar al del siguiente ejemplo podría ser exactamente lo que necesita.

{
  "value": [
    {
      "@search.score": 1,
      "id": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff",
      "palette": "primary colors",
      "color_names": [
        "blue",
        "red",
        "yellow"
      ],
      "color_mediums": [
        "[\"acrylic\",\"oil\",\"pastel\"]",
        "[\"acrylic\",\"pastel\",\"watercolor\"]",
        "[\"acrylic\",\"watercolor\"]"
      ]
    }
  ]
}