Mapear a saída enriquecida para campos em um índice de pesquisa no Azure AI Search

Estágios do indexador

Este artigo explica como configurar mapeamentos de campo de saída, definir um caminho de dados entre estruturas de dados na memória criadas durante o processamento do conjunto de habilidades e campos de destino em um índice de pesquisa. Um mapeamento de campo de saída é definido em um indexador e tem os seguintes elementos:

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

Em contraste com uma definição fieldMappings que mapeia um caminho entre duas estruturas de dados físicos, uma definição outputFieldMappings mapeia enriquecimentos na memória para campos em um índice de pesquisa.

Mapeamentos de campo de saída serão necessários se o indexador tiver um conjunto de habilidades anexado que crie novas informações, como tradução de texto ou extração de frases-chave. Durante a execução do indexador, as informações geradas por IA existem somente na memória. Para manter essas informações em um índice de pesquisa, você precisará informar ao indexador para onde enviar os dados.

Mapeamentos de campo de saída também podem ser usados para recuperar nós específicos no tipo complexo de um documento de origem. Por exemplo, talvez você queira apenas "FullName/LastName" em uma propriedade "FullName" de várias partes. Quando você não precisar da estrutura completa e complexa, poderá nivelar nós individuais em uma estrutura de dados aninhada e, em seguida, usar um mapeamento de campo de saída para enviar a saída para uma coleção de cadeias de caracteres em seu índice de pesquisa.

Os mapeamentos de campo de saída se aplicam a:

  • Conteúdo na memória criado por habilidades ou extraído por um indexador. O campo de origem é um nó em uma árvore de documento enriquecido.

  • Pesquisar índices. Se você estiver preenchendo um repositório de conhecimento, use projeções para a configuração do caminho de dados. Se você estiver preenchendo campos de vetor, os mapeamentos do campo de saída não serão usados.

Os mapeamentos de campo de saída são aplicados após a execução do conjunto de habilidades ou após a quebra de documentos se não houver nenhum conjunto de habilidades associado.

Definir um mapeamento de campo de saída

Mapeamentos de campo de saída são adicionados à outputFieldMappings matriz em uma definição de indexador, normalmente colocada após a matriz fieldMappings. Um mapeamento de campo de saída é composto por três partes.

"fieldMappings": []
"outputFieldMappings": [
  {
    "sourceFieldName": "/document/path-to-a-node-in-an-enriched-document",
    "targetFieldName": "some-search-field-in-an-index",
    "mappingFunction": null
  }
],
Propriedade Descrição
sourceFieldName Obrigatório. Especifica um caminho para conteúdo enriquecido. Um exemplo pode ser /document/content. Consulte Enriquecimentos de referência em um conjunto de habilidades da Pesquisa de IA do Azure para obter sintaxe de caminho e exemplos.
targetFieldName Opcional. Especifica o campo de pesquisa que recebe o conteúdo enriquecido. Os campos de destino devem ser campos ou coleções simples de nível superior. Não pode ser um caminho para um subcampo em um tipo complexo. Se quiser recuperar nós específicos em uma estrutura complexa, poderá nivelar nós individuais na memória e, em seguida, enviar a saída para uma coleção de cadeias de caracteres em seu índice.
mappingFunction Opcional. Adiciona processamento extra fornecido por funções de mapeamento com suporte pelos indexadores. Para nós de enriquecimento, codificação e decodificação são as funções mais usadas.

Use o portal, a API REST ou um SDK do Azure para definir mapeamentos de campo de saída.

Dica

Os indexadores criados pelo assistente de importação de dados incluem mapeamentos de campo de saída gerados pelo assistente. Se você precisar de exemplos, execute o assistente na fonte de dados para ver a definição renderizada.

Use Criar indexador (REST) ou Atualizar indexador (REST) para qualquer versão da API.

Este exemplo adiciona entidades e rótulos de sentimento extraídos da propriedade de conteúdo de um blob a campos em um índice de pesquisa.

PUT https://[service name].search.windows.net/indexers/myindexer?api-version=[api-version]
Content-Type: application/json
api-key: [admin key]
{
    "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"
        }
    ]
}

Para cada mapeamento de campo de saída, defina a localização dos dados na árvore do documento enriquecido (sourceFieldName) e o nome do campo conforme referenciado no índice (targetFieldName). Atribua as funções de mapeamento necessárias para transformar o conteúdo de um campo antes que ele seja armazenado no índice.

Nivelar estruturas complexas em uma coleção de cadeias de caracteres

Se os dados de origem forem compostos por JSON aninhado ou hierárquico, você não poderá usar os mapeamentos de campo para configurar os caminhos de dados. Em vez disso, o índice de pesquisa deve espelhar a estrutura de dados de origem para cada nível para uma importação completa.

Esta seção orienta você por um processo de importação que produz um reflexo um-para-um de um documento complexo nos lados de origem e de destino. Em seguida, ele usa o mesmo documento de origem para ilustrar a recuperação e o nivelamento de nós individuais em coleções de cadeias de caracteres.

Aqui está um exemplo de um documento no Azure Cosmos DB com JSON aninhado:

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

Se você quisesse indexar totalmente o documento de origem acima, criaria uma definição de índice em que os nomes de campo, os níveis e os tipos são refletidos como um tipo complexo. Como não há suporte para mapeamentos de campo para tipos complexos no índice de pesquisa, sua definição de índice deve espelhar o documento de origem.

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

Aqui está uma definição de indexador de exemplo que executa a importação (observe que não há mapeamentos de campo e nenhum conjunto de habilidades).

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

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

O resultado é o documento de pesquisa de exemplo a seguir, semelhante ao original no 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"
          ]
        }
      ]
    }
  ]
}

Uma renderização alternativa em um índice de pesquisa é nivelar nós individuais na estrutura aninhada da origem em uma coleção de cadeias de caracteres em um índice de pesquisa.

Para realizar essa tarefa, você precisará de um outputFieldMappings que mapeie um nó na memória para uma coleção de cadeias de caracteres no índice. Embora os mapeamentos de campo de saída se apliquem principalmente a saídas de habilidades, você também pode usá-los para endereçar nós após “quebra de documento” em que o indexador abre um documento de origem e lê esse documento na memória.

Abaixo está um exemplo de definição de índice, usando coleções de cadeias de caracteres para receber uma saída nivelada:

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

Aqui está a definição do indexador de exemplo, usando outputFieldMappings para associar o JSON aninhado aos campos de coleção de cadeias de caracteres. Observe que o campo de origem usa a sintaxe de caminho para nós de enriquecimento, mesmo que não haja nenhum conjunto de habilidades. Documentos enriquecidos são criados no sistema durante a quebra de documentos, o que significa que você pode acessar nós em cada árvore de documentos, desde que esses nós existam quando o documento é quebrado.

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

Os resultados da definição acima são os seguintes. Simplificar a estrutura, perde contexto nesse caso. Não há mais associações entre uma determinada cor e os meios em que ela está disponível. No entanto, dependendo do cenário, um resultado semelhante ao mostrado abaixo pode ser exatamente o que você precisa.

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

Confira também