Esempio dettagliato di forme e proiezioni in un archivio conoscenze
Questo articolo fornisce un esempio dettagliato che integra concetti di alto livello e articoli basati sulla sintassi illustrando i passaggi di modellazione e proiezione necessari per esprimere completamente l'output di un set di competenze avanzato in un archivio conoscenze.
Se i requisiti dell'applicazione richiedono più competenze e proiezioni, questo esempio può offrire un'idea migliore del modo in cui le forme e le proiezioni si intersecano.
Scaricare le definizioni di esempio
Questo esempio usa l'app Postman e le API REST di ricerca.
Clonare o scaricare azure-search-postman-samples in GitHub e importare la raccolta Projections per eseguire manualmente questo esempio.
Configurare i dati di esempio
I documenti di esempio non sono inclusi nella raccolta Projections, ma i file di dati demo di arricchimento tramite intelligenza artificiale del repository azure-search-sample-data contengono testo e immagini e funzioneranno con le proiezioni descritte in questo esempio.
Creare un contenitore BLOB in Archiviazione di Azure e caricare tutti e 14 gli elementi.
In Archiviazione di Azure copiare un stringa di connessione in modo da poterlo specificare nella raccolta Postman.
Set di competenze di esempio
Per comprendere la dipendenza tra forme e proiezioni, esaminare il set di competenze seguente che crea contenuto arricchito. Questo set di competenze elabora sia immagini non elaborate che testo, producendo output a cui verrà fatto riferimento nelle forme e nelle proiezioni.
Prestare particolare attenzione agli output delle competenze (targetNames). Gli output scritti nell'albero dei documenti arricchiti vengono a cui si fa riferimento nelle proiezioni e nelle forme (tramite le competenze di Shaper).
{
"name": "projections-demo-ss",
"description": "Skillset that enriches blob data found in "merged_content". The enrichment granularity is a document.",
"skills": [
{
"@odata.type": "#Microsoft.Skills.Text.V3.EntityRecognitionSkill",
"name": "#1",
"description": null,
"context": "/document/merged_content",
"categories": [
"Person",
"Quantity",
"Organization",
"URL",
"Email",
"Location",
"DateTime"
],
"defaultLanguageCode": "en",
"minimumPrecision": null,
"inputs": [
{
"name": "text",
"source": "/document/merged_content"
},
{
"name": "languageCode",
"source": "/document/language"
}
],
"outputs": [
{
"name": "persons",
"targetName": "people"
},
{
"name": "organizations",
"targetName": "organizations"
},
{
"name": "locations",
"targetName": "locations"
}
]
},
{
"@odata.type": "#Microsoft.Skills.Text.KeyPhraseExtractionSkill",
"name": "#2",
"description": null,
"context": "/document/merged_content",
"defaultLanguageCode": "en",
"maxKeyPhraseCount": null,
"inputs": [
{
"name": "text",
"source": "/document/merged_content"
},
{
"name": "languageCode",
"source": "/document/language"
}
],
"outputs": [
{
"name": "keyPhrases",
"targetName": "keyphrases"
}
]
},
{
"@odata.type": "#Microsoft.Skills.Text.LanguageDetectionSkill",
"name": "#3",
"description": null,
"context": "/document",
"inputs": [
{
"name": "text",
"source": "/document/merged_content"
}
],
"outputs": [
{
"name": "languageCode",
"targetName": "language"
}
]
},
{
"@odata.type": "#Microsoft.Skills.Text.MergeSkill",
"name": "#4",
"description": null,
"context": "/document",
"insertPreTag": " ",
"insertPostTag": " ",
"inputs": [
{
"name": "text",
"source": "/document/content"
},
{
"name": "itemsToInsert",
"source": "/document/normalized_images/*/text"
},
{
"name": "offsets",
"source": "/document/normalized_images/*/contentOffset"
}
],
"outputs": [
{
"name": "mergedText",
"targetName": "merged_content"
}
]
},
{
"@odata.type": "#Microsoft.Skills.Vision.OcrSkill",
"name": "#5",
"description": null,
"context": "/document/normalized_images/*",
"textExtractionAlgorithm": "printed",
"lineEnding": "Space",
"defaultLanguageCode": "en",
"detectOrientation": true,
"inputs": [
{
"name": "image",
"source": "/document/normalized_images/*"
}
],
"outputs": [
{
"name": "text",
"targetName": "text"
},
{
"name": "layoutText",
"targetName": "layoutText"
}
]
}
],
"cognitiveServices": {
"@odata.type": "#Microsoft.Azure.Search.CognitiveServicesByKey",
"description": "An Azure AI services resource in the same region as Search.",
"key": "<Azure AI services All-in-ONE KEY>"
},
"knowledgeStore": null
}
Competenza shaper di esempio
Una competenza Shaper è un'utilità per l'uso di contenuto arricchito esistente invece di creare nuovi contenuti arricchiti. L'aggiunta di un shaper a un set di competenze consente di creare una forma personalizzata che è possibile proiettare in una tabella o in un archivio BLOB. Senza una forma personalizzata, le proiezioni sono limitate a fare riferimento a un singolo nodo (una proiezione per output), che non è adatta per le tabelle. La creazione di una forma personalizzata aggrega vari elementi in un nuovo intero logico che può essere proiettato come una singola tabella o sezionato e distribuito in una raccolta di tabelle.
In questo esempio la forma personalizzata combina i metadati del BLOB e le entità identificate e le frasi chiave. La forma personalizzata viene chiamata projectionShape
ed è padre in /document
.
Uno degli scopi del shaping è garantire che tutti i nodi di arricchimento siano espressi in JSON ben formato, che è necessario per proiettare nell'archivio conoscenze. Ciò vale soprattutto quando un albero di arricchimento contiene nodi che non sono json ben formati( ad esempio, quando un arricchimento viene padre di una primitiva come una stringa).
Si notino gli ultimi due nodi e KeyPhrases
Entities
. Questi vengono racchiusi in un oggetto JSON valido con .sourceContext
Questa operazione è necessaria perché keyphrases
e entities
sono arricchimenti nelle primitive e devono essere convertiti in JSON validi prima che possano essere proiettati.
{
"@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
"name": "ShaperForTables",
"description": null,
"context": "/document",
"inputs": [
{
"name": "metadata_storage_content_type",
"source": "/document/metadata_storage_content_type",
"sourceContext": null,
"inputs": []
},
{
"name": "metadata_storage_name",
"source": "/document/metadata_storage_name",
"sourceContext": null,
"inputs": []
},
{
"name": "metadata_storage_path",
"source": "/document/metadata_storage_path",
"sourceContext": null,
"inputs": []
},
{
"name": "metadata_content_type",
"source": "/document/metadata_content_type",
"sourceContext": null,
"inputs": []
},
{
"name": "keyPhrases",
"source": null,
"sourceContext": "/document/merged_content/keyphrases/*",
"inputs": [
{
"name": "KeyPhrases",
"source": "/document/merged_content/keyphrases/*"
}
]
},
{
"name": "Entities",
"source": null,
"sourceContext": "/document/merged_content/entities/*",
"inputs": [
{
"name": "Entities",
"source": "/document/merged_content/entities/*/name"
}
]
}
],
"outputs": [
{
"name": "output",
"targetName": "projectionShape"
}
]
}
Aggiungere shaper a un set di competenze
Il set di competenze di esempio introdotto all'inizio di questo articolo non includeva la competenza Shaper, ma le competenze di Shaper appartengono a un set di competenze e vengono spesso posizionate verso la fine.
All'interno di un set di competenze, una competenza Shaper potrebbe essere simile alla seguente:
"name": "projections-demo-ss",
"skills": [
{
<Shaper skill goes here>
}
],
"cognitiveServices": "A key goes here",
"knowledgeStore": []
}
Creazione di progetti in tabelle
Attingendo agli esempi precedenti, esiste una quantità nota di arricchimenti e forme di dati a cui è possibile fare riferimento nelle proiezioni di tabella. Nella proiezione delle tabelle seguente vengono definite tre tabelle impostando le tableName
proprietà , source
e generatedKeyName
.
Tutte e tre queste tabelle verranno correlate tramite chiavi generate e dall'elemento padre /document/projectionShape
condiviso.
"knowledgeStore" : {
"storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
"projections": [
{
"tables": [
{
"tableName": "tblDocument",
"generatedKeyName": "Documentid",
"source": "/document/projectionShape"
},
{
"tableName": "tblKeyPhrases",
"generatedKeyName": "KeyPhraseid",
"source": "/document/projectionShape/keyPhrases/*"
},
{
"tableName": "tblEntities",
"generatedKeyName": "Entityid",
"source": "/document/projectionShape/Entities/*"
}
],
"objects": [],
"files": []
}
]
}
Testare il lavoro
È possibile controllare le definizioni di proiezione seguendo questa procedura:
Impostare la proprietà dell'archivio
storageConnectionString
conoscenze su un account di archiviazione per utilizzo generico V2 valido stringa di connessione.Aggiornare il set di competenze inviando la richiesta PUT.
Dopo aver aggiornato il set di competenze, eseguire l'indicizzatore.
È ora disponibile una proiezione funzionante con tre tabelle. L'importazione di queste tabelle in Power BI dovrebbe comportare l'individuazione delle relazioni da parte di Power BI.
Prima di passare all'esempio successivo, esaminiamo gli aspetti della proiezione di tabella per comprendere i meccanismi di sezionamento e i dati correlati.
Sezionamento di una tabella in più tabelle figlio
Il sezionamento è una tecnica che suddivide un'intera forma consolidata in parti costitutive. Il risultato è costituito da tabelle separate ma correlate che è possibile usare singolarmente.
Nell'esempio è projectionShape
la forma consolidata (o nodo di arricchimento). Nella definizione projectionShape
di proiezione viene suddiviso in tabelle aggiuntive, che consente di estrarre parti della forma keyPhrases
e Entities
. In Power BI questa opzione è utile perché più entità e keyPhrase sono associate a ogni documento e si otterranno altre informazioni se è possibile visualizzare entità e keyPhrase come dati classificati.
Il sezionamento genera in modo implicito una relazione tra le tabelle padre e figlio, utilizzando nella generatedKeyName
tabella padre per creare una colonna con lo stesso nome nella tabella figlio.
Denominazione delle relazioni
Le generatedKeyName
proprietà e referenceKeyName
vengono usate per correlare i dati tra tabelle o anche tra tipi di proiezione. Ogni riga della tabella figlio ha una proprietà che punta di nuovo all'elemento padre. Il nome della colonna o della proprietà nell'elemento figlio è quello referenceKeyName
dell'elemento padre. referenceKeyName
Quando non viene specificato, il servizio lo usa come generatedKeyName
predefinito dal padre.
Power BI si basa su queste chiavi generate per individuare le relazioni all'interno delle tabelle. Se è necessaria la colonna nella tabella figlio denominata in modo diverso, impostare la referenceKeyName
proprietà nella tabella padre. Un esempio è impostare come generatedKeyName
ID nella tabella tblDocument e come referenceKeyName
DocumentID. Ciò comporta la colonna nelle tabelle tblEntities e tblKeyPhrases contenenti l'ID documento denominato DocumentID.
Progetto di documenti BLOB
Le proiezioni di oggetti sono rappresentazioni JSON dell'albero di arricchimento che possono essere originate da qualsiasi nodo. Rispetto alle proiezioni di tabelle, le proiezioni di oggetti sono più semplici da definire e vengono usate durante la proiezione di interi documenti. Le proiezioni di oggetti sono limitate a una singola proiezione in un contenitore e non possono essere sezionate.
Per definire una proiezione di oggetti, usare la objects
matrice nella proprietà projections.
L'origine è il percorso di un nodo dell'albero di arricchimento che è la radice della proiezione. Anche se non è obbligatorio, il percorso del nodo è in genere l'output di una competenza shaper. Ciò è dovuto al fatto che la maggior parte delle competenze non restituisce oggetti JSON validi autonomamente, il che significa che è necessaria una forma di data shaping. In molti casi, è possibile usare la stessa competenza shaper che crea una proiezione di tabella per generare una proiezione di oggetti. In alternativa, l'origine può anche essere impostata su un nodo con una forma inline per fornire la struttura.
La destinazione è sempre un contenitore BLOB.
L'esempio seguente proietta singoli documenti di hotel, un documento di hotel per BLOB, in un contenitore denominato hotels
.
"knowledgeStore": {
"storageConnectionString": "an Azure storage connection string",
"projections" : [
{
"tables": [ ]
},
{
"objects": [
{
"storageContainer": "hotels",
"source": "/document/objectprojection",
}
]
},
{
"files": [ ]
}
]
}
L'origine è l'output di una competenza Shaper denominata "objectprojection". Ogni BLOB avrà una rappresentazione JSON di ogni input di campo.
{
"@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
"name": "#3",
"description": null,
"context": "/document",
"inputs": [
{
"name": "HotelId",
"source": "/document/HotelId"
},
{
"name": "HotelName",
"source": "/document/HotelName"
},
{
"name": "Category",
"source": "/document/Category"
},
{
"name": "keyPhrases",
"source": "/document/HotelId/keyphrases/*"
},
],
"outputs": [
{
"name": "output",
"targetName": "objectprojection"
}
]
}
Creazione di un file di immagine
Le proiezioni di file sono sempre immagini binarie, normalizzate, in cui la normalizzazione si riferisce al ridimensionamento e alla rotazione potenziali da usare nell'esecuzione del set di competenze. Le proiezioni di file, simili alle proiezioni di oggetti, vengono create come BLOB in Archiviazione di Azure e contengono l'immagine.
Per definire una proiezione di file, usare la files
matrice nella proprietà projections.
L'origine è sempre /document/normalized_images/*
. Le proiezioni di file agiscono solo sulla normalized_images
raccolta. Né gli indicizzatori né un set di competenze passeranno attraverso l'immagine originale non normalizzata.
La destinazione è sempre un contenitore BLOB, con un prefisso di cartella del valore con codifica Base64 dell'ID documento. Le proiezioni di file non possono condividere lo stesso contenitore delle proiezioni di oggetti e devono essere proiettate in un contenitore diverso.
L'esempio seguente proietta tutte le immagini normalizzate estratte dal nodo del documento di un documento arricchito, in un contenitore denominato myImages
.
"knowledgeStore" : {
"storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
"projections": [
{
"tables": [ ],
"objects": [ ],
"files": [
{
"storageContainer": "myImages",
"source": "/document/normalized_images/*"
}
]
}
]
}
Progetto in più tipi
Uno scenario più complesso potrebbe richiedere di proiettare il contenuto tra i tipi di proiezione. Ad esempio, proiettando frasi chiave ed entità in tabelle, salvando i risultati OCR di testo e layout come oggetti e quindi proiettando le immagini come file.
Passaggi per più tipi di proiezione:
- Creare una tabella con una riga per ogni documento.
- Creare una tabella correlata alla tabella documento con ogni frase chiave identificata come riga in questa tabella.
- Creare una tabella correlata alla tabella dei documenti con ogni entità identificata come riga in questa tabella.
- Creare una proiezione di oggetti con il testo del layout per ogni immagine.
- Creare una proiezione di file proiettando ogni immagine estratta.
- Creare una tabella di riferimento incrociato contenente riferimenti alla tabella del documento, alla proiezione di oggetti con il testo del layout e alla proiezione di file.
Modellare i dati per la proiezione incrociata
Per ottenere le forme necessarie per queste proiezioni, iniziare aggiungendo una nuova competenza Shaper che crea un oggetto shaped denominato crossProjection
.
{
"@odata.type": "#Microsoft.Skills.Util.ShaperSkill",
"name": "ShaperForCrossProjection",
"description": null,
"context": "/document",
"inputs": [
{
"name": "metadata_storage_name",
"source": "/document/metadata_storage_name",
"sourceContext": null,
"inputs": []
},
{
"name": "keyPhrases",
"source": null,
"sourceContext": "/document/merged_content/keyphrases/*",
"inputs": [
{
"name": "KeyPhrases",
"source": "/document/merged_content/keyphrases/*"
}
]
},
{
"name": "entities",
"source": null,
"sourceContext": "/document/merged_content/entities/*",
"inputs": [
{
"name": "Entities",
"source": "/document/merged_content/entities/*/name"
}
]
},
{
"name": "images",
"source": null,
"sourceContext": "/document/normalized_images/*",
"inputs": [
{
"name": "image",
"source": "/document/normalized_images/*"
},
{
"name": "layoutText",
"source": "/document/normalized_images/*/layoutText"
},
{
"name": "ocrText",
"source": "/document/normalized_images/*/text"
}
]
}
],
"outputs": [
{
"name": "output",
"targetName": "crossProjection"
}
]
}
Definire proiezioni di tabelle, oggetti e file
Dall'oggetto crossProjection consolidato, suddividere l'oggetto in più tabelle, acquisire l'output OCR come BLOB e quindi salvare l'immagine come file (anche nell'archivio BLOB).
"knowledgeStore" : {
"storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
"projections": [
{
"tables": [
{
"tableName": "crossDocument",
"generatedKeyName": "Id",
"source": "/document/crossProjection"
},
{
"tableName": "crossEntities",
"generatedKeyName": "EntityId",
"source": "/document/crossProjection/entities/*"
},
{
"tableName": "crossKeyPhrases",
"generatedKeyName": "KeyPhraseId",
"source": "/document/crossProjection/keyPhrases/*"
},
{
"tableName": "crossReference",
"generatedKeyName": "CrossId",
"source": "/document/crossProjection/images/*"
}
],
"objects": [
{
"storageContainer": "crossobject",
"generatedKeyName": "crosslayout",
"source": null,
"sourceContext": "/document/crossProjection/images/*/layoutText",
"inputs": [
{
"name": "OcrLayoutText",
"source": "/document/crossProjection/images/*/layoutText"
}
]
}
],
"files": [
{
"storageContainer": "crossimages",
"generatedKeyName": "crossimages",
"source": "/document/crossProjection/images/*/image"
}
]
}
]
}
Le proiezioni di oggetti richiedono un nome contenitore per ogni proiezione. Le proiezioni di oggetti e le proiezioni di file non possono condividere un contenitore.
Relazioni tra le proiezioni di tabelle, oggetti e file
In questo esempio viene evidenziata anche un'altra funzionalità delle proiezioni. Definendo più tipi di proiezioni all'interno dello stesso oggetto di proiezione, esiste una relazione espressa all'interno e tra i diversi tipi (tabelle, oggetti, file). In questo modo è possibile iniziare con una riga di tabella per un documento e trovare tutto il testo OCR per le immagini all'interno del documento nella proiezione dell'oggetto.
Se non si desidera che i dati correlati, definire le proiezioni in gruppi di proiezione diversi. Ad esempio, il frammento di codice seguente comporterà la correlazione delle tabelle, ma senza relazioni tra le tabelle e le proiezioni dell'oggetto (testo OCR).
I gruppi di proiezioni sono utili quando si desidera proiettare gli stessi dati in forme diverse per esigenze diverse. Ad esempio, un gruppo di proiezione per il dashboard di Power BI e un altro gruppo di proiezione per l'acquisizione dei dati usati per eseguire il training di un modello di Machine Learning incapsulato in una competenza personalizzata.
Quando si compilano proiezioni di tipi diversi, vengono generate prima proiezioni di file e oggetti e i percorsi vengono aggiunti alle tabelle.
"knowledgeStore" : {
"storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
"projections": [
{
"tables": [
{
"tableName": "unrelatedDocument",
"generatedKeyName": "Documentid",
"source": "/document/projectionShape"
},
{
"tableName": "unrelatedKeyPhrases",
"generatedKeyName": "KeyPhraseid",
"source": "/document/projectionShape/keyPhrases"
}
],
"objects": [
],
"files": []
},
{
"tables": [],
"objects": [
{
"storageContainer": "unrelatedocrtext",
"source": null,
"sourceContext": "/document/normalized_images/*/text",
"inputs": [
{
"name": "ocrText",
"source": "/document/normalized_images/*/text"
}
]
},
{
"storageContainer": "unrelatedocrlayout",
"source": null,
"sourceContext": "/document/normalized_images/*/layoutText",
"inputs": [
{
"name": "ocrLayoutText",
"source": "/document/normalized_images/*/layoutText"
}
]
}
],
"files": []
}
]
}
Passaggi successivi
L'esempio in questo articolo illustra modelli comuni su come creare proiezioni. Ora che si ha una buona conoscenza dei concetti, è possibile creare proiezioni per uno scenario specifico.