Eseguire il mapping dell'output arricchito ai campi di un indice di ricerca in Azure AI Search

Fasi dell’indicizzatore

Questo articolo illustra come configurare i mapping dei campi di output, definendo un percorso dati tra i dati in memoria generati durante l’elaborazione del set di competenze e i campi di destinazione di un indice di ricerca. Durante l'esecuzione dell'indicizzatore, le informazioni generate da competenze esistono solo in memoria. Per rendere persistenti queste informazioni in un indice di ricerca, è necessario indicare all'indicizzatore dove inviare i dati.

Viene definito un mapping dei campi di output in un indicizzatore e include gli elementi seguenti:

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

A differenza di una definizione fieldMappings che esegue il mapping di un percorso tra campi di origine verbatim e campi di indice, una definizione outputFieldMappings esegue il mapping degli arricchimenti in memoria ai campi in un indice di ricerca.

Prerequisiti

  • Indicizzatore, indice, origine dati e set di competenze.

  • I campi di indice devono essere campi semplici o di primo livello. Non è possibile restituire un tipo complesso, ma se si dispone di un tipo complesso, è possibile usare una definizione di campo di output per rendere flat parti del tipo complesso e inviarle a una raccolta in un indice di ricerca.

Quando usare un mapping dei campi di output

I mapping dei campi di output sono necessari se l'indicizzatore dispone di un set di competenze collegato che crea nuove informazioni che si desidera avere nell'indice. Alcuni esempi:

  • Vettori provenienti dalle competenze di incorporamento
  • Testo OCR proveniente dalle competenze dell'immagine
  • Località, organizzazioni o persone provenienti da competenze di riconoscimento delle entità

I mapping dei campi di output possono essere usati anche per:

  • Creare più copie del contenuto generato (mapping dei campi di output da uno a molti).

  • Rendere flat il tipo complesso di un documento di origine. Si supponga, ad esempio, che i documenti di origine abbiano un tipo complesso, ad esempio un indirizzo multipart, e che si voglia solo la città. È possibile usare un mapping dei campi di output per rendere flat una struttura di dati annidata e quindi usare un mapping dei campi di output per inviare l'output a una raccolta di stringhe nell'indice di ricerca.

I mapping dei campi di output si applicano solo agli indici di ricerca. Se si popola un archivio conoscenze, usare le proiezioni per la configurazione del percorso dati.

Definire un mapping dei campi di output

I mapping dei campi di output vengono aggiunti alla matrice outputFieldMappings in una definizione dell'indicizzatore, in genere posizionati dopo la matrice fieldMappings. Un mapping dei campi di output è costituito da tre parti.

È possibile usare l'API REST o un SDK Azure per definire i mapping dei campi di output.

Suggerimento

Gli indicizzatori creati dalla Importazione guidata dati includono i mapping dei campi di output generati dalla procedura guidata. Se sono necessari esempi, eseguire la procedura guidata sull'origine dati per visualizzare i mapping dei campi di output nell'indicizzatore.

  1. Usare Crea indicizzatore o Crea o Aggiorna indicizzatore o un metodo equivalente in Azure SDK. Ecco un esempio di definizione dell'indicizzatore.

    {
       "name": "myindexer",
       "description": null,
       "dataSourceName": "mydatasource",
       "targetIndexName": "myindex",
       "schedule": { },
       "parameters": { },
       "fieldMappings": [],
       "outputFieldMappings": [],
       "disabled": false,
       "encryptionKey": { }
     }
    
  2. Compilare la matrice outputFieldMappings per specificare i mapping. Un mapping dei campi è costituito da tre parti.

    "outputFieldMappings": [
      {
        "sourceFieldName": "/document/path-to-a-node-in-an-enriched-document",
        "targetFieldName": "some-search-field-in-an-index",
        "mappingFunction": null
      }
    ]
    
    Proprietà Descrizione
    sourceFieldName Obbligatorio. Specifica un percorso per il contenuto arricchito. ad esempio /document/content. Per esempi e sintassi percorsi, vedere Arricchimenti di riferimento in un set di competenze di Azure AI Search.
    targetFieldName Facoltativo. Specifica il campo di ricerca che riceve il contenuto arricchito. I campi di destinazione devono essere campi o raccolte semplici di primo livello. Non può essere un percorso di un sottocampo in un tipo complesso. Se si desidera recuperare nodi specifici in una struttura complessa, è possibile rendere flat i singoli nodi in memoria e quindi inviare l'output a una raccolta di stringhe nell'indice.
    mappingFunction Facoltativo. Aggiunge un'elaborazione aggiuntiva fornita dalle funzioni di mapping supportate dagli indicizzatori. Per i nodi di arricchimento, la codifica e la decodifica sono le funzioni usate più di frequente.
  3. targetFieldName è sempre il nome del campo nell'indice di ricerca.

  4. sourceFieldName è un percorso di un nodo nel documento arricchito. È l'output di una competenza. Il percorso inizia sempre con /document e, se si esegue l'indicizzazione da un BLOB, il secondo elemento del percorso è /content. Il terzo elemento è il valore prodotto dalla competenza. Per altre informazioni ed esempi, vedere Arricchimenti di riferimento in un set di competenze di Azure AI Search.

    In questo esempio vengono aggiunte ai campi in un indice di ricerca entità ed etichette del sentiment estratte dalla proprietà del contenuto di un BLOB.

    {
        "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. Assegnare le funzioni di mapping necessarie per trasformare il contenuto di un campo prima che venga archiviato nell'indice. Per i nodi di arricchimento, la codifica e la decodifica sono le funzioni usate più di frequente.

Mapping dei campi di output uno a molti

È possibile usare un mapping dei campi di output per instradare un singolo campo di origine a più campi in un indice di ricerca. Questa operazione può essere eseguita per i test di confronto o se si vogliono campi con attributi diversi.

Si supponga di avere un set di competenze che genera incorporamenti per un campo vettoriale e un indice con più campi vettoriali che variano in base alle impostazioni di algoritmo e compressione. All'interno dell'indicizzatore eseguire il mapping dell'output della competenza di incorporamento a ognuno dei campi vettoriali multipli in un indice di ricerca.

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

Il percorso del campo di origine è l'output della competenza. In questo esempio l'output è text_vector. Il nome della destinazione è una proprietà facoltativa. Se non si assegna al mapping di output un nome di destinazione, il percorso sarà embedding, o più precisamente /document/content/embedding.

{
  "name": "test-vector-size-ss",  
  "description": "Generate embeddings using AOAI",
  "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
    }
  ]
}

Rendere flat strutture complesse in una raccolta di stringhe

Se i dati di origine sono costituiti da JSON annidato o gerarchico, non è possibile usare i mapping dei campi per configurare i percorsi dei dati. L'indice di ricerca deve invece eseguire il mirroring della struttura dei dati di origine a ogni livello per un'importazione completa.

Questa sezione illustra un processo di importazione che produce una riflessione uno a uno di un documento complesso, sia sul lato di origine che su quello di destinazione. Successivamente, usa lo stesso documento di origine per illustrare il recupero e l’operazione con cui rendere flat i singoli nodi in raccolte di stringhe.

Ecco un esempio di documento in Azure Cosmos DB con JSON annidato:

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

Se si vuole indicizzare completamente il documento di origine precedente, è necessario creare una definizione di indice in cui i nomi dei campi, i livelli e i tipi vengono riflessi come tipo complesso. Poiché i mapping dei campi non sono supportati per i tipi complessi nell'indice di ricerca, la definizione dell'indice deve eseguire il mirroring del documento di origine.

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

Ecco una definizione di indicizzatore di esempio che esegue l'importazione (si noti che non sono presenti mapping di campi né set di competenze).

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

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

Il risultato è il seguente documento di ricerca di esempio, simile all'originale in Azure Cosmos DB.

{
  "value": [
    {
      "@search.score": 1,
      "id": "240a98f5-90c9-406b-a8c8-f50ff86f116c",
      "palette": "primary colors",
      "colors": [
        {
          "name": "blue",
          "medium": [
            "acrylic",
            "oil",
            "pastel"
          ]
        },
        {
          "name": "red",
          "medium": [
            "acrylic",
            "pastel",
            "watercolor"
          ]
        },
        {
          "name": "yellow",
          "medium": [
            "acrylic",
            "watercolor"
          ]
        }
      ]
    }
  ]
}

Un rendering alternativo in un indice di ricerca consiste nel rendere flat i singoli nodi nella struttura nidificata dell'origine in una raccolta di stringhe di un indice di ricerca.

Per eseguire questa attività, è necessario un oggetto outputFieldMappings che esegue il mapping di un nodo in memoria a una raccolta di stringhe nell'indice. Anche se i mapping dei campi di output si applicano principalmente agli output delle competenze, è possibile usarli anche per indirizzare i nodi dopo il "cracking di documenti" in cui l'indicizzatore apre un documento di origine e lo legge in memoria.

Di seguito è riportata una definizione di indice di esempio, che usa raccolte di stringhe per ricevere l'output reso flat:

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

Ecco la definizione dell'indicizzatore di esempio, usando outputFieldMappings per associare il codice JSON annidato ai campi della raccolta di stringhe. Si noti che il campo di origine usa la sintassi del percorso dei nodi di arricchimento, anche se non è presente alcun set di competenze. I documenti arricchiti vengono creati nel sistema durante il cracking dei documenti, il che significa che è possibile accedere ai nodi in ogni albero dei documenti, purché tali nodi esistano quando viene esgeuito il cracking del 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"
    }
  ]
}

I risultati della definizione precedente sono i seguenti. La semplificazione della struttura perde il contesto in questo caso. Non sono più presenti associazioni tra un determinato colore e i supporti in cui è disponibile. Tuttavia, a seconda dello scenario, un risultato simile a quello illustrato di seguito potrebbe essere esattamente quello necessario.

{
  "value": [
    {
      "@search.score": 1,
      "id": "240a98f5-90c9-406b-a8c8-f50ff86f116c",
      "palette": "primary colors",
      "color_names": [
        "blue",
        "red",
        "yellow"
      ],
      "color_mediums": [
        "[\"acrylic\",\"oil\",\"pastel\"]",
        "[\"acrylic\",\"pastel\",\"watercolor\"]",
        "[\"acrylic\",\"watercolor\"]"
      ]
    }
  ]
}

Vedi anche