Gedetailleerd voorbeeld van vormen en projecties in een kennisopslag

Dit artikel bevat een gedetailleerd voorbeeld dat een aanvulling is op concepten op hoog niveau en artikelen op basis van syntaxis door u door de stappen voor vormgeving en projectie te laten lopen die nodig zijn om de uitvoer van een uitgebreide vaardighedenset in een kennisopslag volledig uit te drukken.

Als uw toepassingsvereisten meerdere vaardigheden en projecties nodig hebben, kan dit voorbeeld u een beter idee geven van hoe vormen en projecties elkaar kruisen.

Voorbeelddefinities downloaden

In dit voorbeeld worden de Postman Desktop-toepassing en de Search REST API's gebruikt.

Kloon of download azure-search-postman-samples op GitHub importeer de verzameling Projecties om dit voorbeeld zelf te door te nemen.

Voorbeeldgegevens instellen

Voorbeelddocumenten zijn niet specifiek opgenomen in de verzameling Projecties, maar de ai-verrijkingsdemogegevensbestanden uit de azure-search-sample-data-repo bevatten tekst en afbeeldingen en werken met de projecties die in dit voorbeeld worden beschreven.

Maak een blobcontainer in Azure Storage en upload alle 14 items.

In Azure Storage kopieert u een connection string zodat u deze kunt opgeven in de Postman-verzameling.

Voorbeeldvaardighedenset

Als u de afhankelijkheid tussen vormen en projecties wilt begrijpen, bekijkt u de volgende vaardighedenset die verrijkte inhoud maakt. Deze vaardighedenset verwerkt zowel onbewerkte afbeeldingen als tekst, en produceert uitvoer waarnaar wordt verwezen in vormen en projecties.

Let goed op de uitvoer van vaardigheden (targetNames). Naar uitvoer die naar de verrijkte documentstructuur wordt geschreven, wordt verwezen in projecties en vormen (via Shaper-vaardigheden).

{
    "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": "A Cognitive Services resource in the same region as Search.",
        "key": "<COGNITIVE SERVICES All-in-ONE KEY>"
    },
    "knowledgeStore": null
}

Voorbeeld van shaper-vaardigheid

Een Shaper-vaardigheid is een hulpprogramma voor het werken met bestaande verrijkte inhoud in plaats van nieuwe verrijkte inhoud te maken. Door een Shaper toe te voegen aan een vaardighedenset kunt u een aangepaste vorm maken die u kunt projecteren in tabel- of blobopslag. Zonder een aangepaste vorm zijn projecties beperkt tot het verwijzen naar één knooppunt (één projectie per uitvoer), wat niet geschikt is voor tabellen. Door een aangepaste vorm te maken, worden verschillende elementen samengevoegd in een nieuw logisch geheel dat kan worden geprojecteerd als één tabel of kan worden gesegmenteerd en gedistribueerd over een verzameling tabellen.

In dit voorbeeld combineert de aangepaste vorm blobmetagegevens en geïdentificeerde entiteiten en sleuteltermen. De aangepaste vorm wordt projectionShape aangeroepen en wordt bovenliggend onder /document .

Een doel van het vormgeven is ervoor te zorgen dat alle verrijkingsknooppunten worden uitgedrukt in een goed gevormde JSON, wat vereist is voor projecteren in een kennisopslag. Dit geldt met name wanneer een verrijkingsstructuur knooppunten bevat die geen goed gevormde JSON zijn (bijvoorbeeld wanneer een verrijking boven een primitieve zoals een tekenreeks staat).

Let op de laatste twee knooppunten, KeyPhrases en Entities . Deze worden verpakt in een geldig JSON-object met de sourceContext . Dit is vereist omdat en verrijkingen op primitieven zijn en moeten worden geconverteerd naar geldige keyphrases entities JSON voordat ze kunnen worden geprojecteerd.

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

Shapers toevoegen aan een vaardighedenset

De voorbeeldvaardighedenset die aan het begin van dit artikel is geïntroduceerd, bevat niet de Shaper-vaardigheid, maar Shaper-vaardigheden horen in een vaardighedenset en worden vaak aan het einde geplaatst.

Binnen een vaardighedenset kan een Shaper-vaardigheid er als volgende uitzien:

    "name": "projections-demo-ss",
    "skills": [
        {
            <Shaper skill goes here>
            }
        ],
    "cognitiveServices":  "A key goes here",
    "knowledgeStore": []
}  

Projecteren naar tabellen

Op basis van de bovenstaande voorbeelden is er een bekend aantal verrijkingen en gegevensvormen waarnaar kan worden verwezen in tabelprojecties. In de onderstaande tabelprojectie worden drie tabellen gedefinieerd door de tableName eigenschappen , en in te source generatedKeyName stellen.

Alle drie deze tabellen worden gerelateerd via gegenereerde sleutels en door de gedeelde bovenliggende /document/projectionShape .

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

Uw werk testen

U kunt projectiedefinities controleren door de volgende stappen uit te voeren:

  1. Stel de eigenschap van het kennisopslag storageConnectionString in op een geldig V2-opslagaccount voor algemeen gebruik connection string.

  2. Werk de vaardighedenset bij door de PUT-aanvraag uit te geven.

  3. Nadat u de vaardighedenset hebt bijgewerkt, moet u de indexer uitvoeren.

U hebt nu een werkende projectie met drie tabellen. Het importeren van deze tabellen in Power BI moet resulteren in Power BI relaties automatisch te detecteren.

Voordat we verder gaan met het volgende voorbeeld, gaan we terug naar aspecten van de tabelprojectie om inzicht te krijgen in de mechanismen van het opsliceren en met elkaar in verband brengen van gegevens.

Een tabel in meerdere onderliggende tabellen opsliceren

Slicing is een techniek die een volledige geconsolideerde vorm in samenstellende delen subdiveert. Het resultaat bestaat uit afzonderlijke, maar gerelateerde tabellen die u afzonderlijk kunt gebruiken.

In het voorbeeld projectionShape is de geconsolideerde vorm (of verrijkings-knooppunt). In de projectiedefinitie wordt gesegmenteerd in extra tabellen, waarmee u delen van de vorm kunt op projectionShape halen, keyPhrases en Entities . In Power BI is dit handig omdat aan elk document meerdere entiteiten en keyPhrases zijn gekoppeld. Als u entiteiten en keyPhrases als gecategoriseerde gegevens ziet, krijgt u meer inzichten.

Slicing genereert impliciet een relatie tussen de bovenliggende en onderliggende tabellen, met behulp van de in de bovenliggende tabel om een kolom met dezelfde naam te maken generatedKeyName in de onderliggende tabel.

Naamgevingsrelaties

De generatedKeyName eigenschappen en worden gebruikt om gegevens in verschillende tabellen of zelfs in verschillende referenceKeyName projectietypen te relateren. Elke rij in de onderliggende tabel heeft een eigenschap die naar het bovenliggende object verwijst. De naam van de kolom of eigenschap in het onderliggende object is referenceKeyName de van het bovenliggende object. Als de referenceKeyName niet is opgegeven, wordt deze standaard ingesteld op de generatedKeyName van het bovenliggende.

Power BI is afhankelijk van deze gegenereerde sleutels om relaties in de tabellen te ontdekken. Als u de kolom in de onderliggende tabel met een andere naam nodig hebt, stelt u de referenceKeyName eigenschap in op de bovenliggende tabel. Een voorbeeld hiervan is het instellen van generatedKeyName de als id voor de tabel tblDocument en de als referenceKeyName DocumentID. Dit zou ertoe leiden dat de kolom in de tabellen tblEntities en tblKeyPhrases met de document-id de naam DocumentID heeft.

Blobdocumenten projecteren

Objectprojecties zijn JSON-weergaven van de verrijkingsstructuur die kunnen worden gebruikt vanuit elk knooppunt. In vergelijking met tabelprojecties zijn objectprojecties eenvoudiger te definiëren en worden ze gebruikt bij het projecteren van hele documenten. Objectprojecties zijn beperkt tot één projectie in een container en kunnen niet worden gesegmenteerd.

Als u een objectprojectie wilt definiëren, gebruikt u objects de matrix in de eigenschap projections.

De bron is het pad naar een knooppunt van de verrijkingsstructuur dat de hoofdmap van de projectie is. Hoewel dit niet vereist is, is het knooppuntpad meestal de uitvoer van een Shaper-vaardigheid. Dit komt doordat de meeste vaardigheden zelf geen geldige JSON-objecten produceren, wat betekent dat er een vorm van vormgeving nodig is. In veel gevallen kan dezelfde Shaper-vaardigheid waarmee een tabelprojectie wordt gemaakt, worden gebruikt om een objectprojectie te genereren. De bron kan ook worden ingesteld op een knooppunt met een inline-vormgeving om de structuur te bieden.

Het doel is altijd een blobcontainer.

In het volgende voorbeeld worden afzonderlijke hoteldocumenten, één hoteldocument per blob, in een container met de naam hotels projecten.

"knowledgeStore": {
  "storageConnectionString": "an Azure storage connection string",
  "projections" : [
    {
      "tables": [ ]
    },
    {
      "objects": [
        {
        "storageContainer": "hotels",
        "source": "/document/objectprojection",
        }
      ]
    },
    {
        "files": [ ]
    }
  ]
}

De bron is de uitvoer van een Shaper-vaardigheid met de naam 'objectprojection'. Elke blob heeft een JSON-weergave van elke veldinvoer.

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

Een afbeeldingsbestand projecteren

Bestandsprojecties zijn altijd binaire, genormaliseerde afbeeldingen, waarbij normalisatie verwijst naar mogelijke formaat- en rotatiemogelijkheden voor gebruik bij het uitvoeren van vaardighedensets. Bestandsprojecties, vergelijkbaar met objectprojecties, worden gemaakt als blobs in Azure Storage en bevatten de afbeelding.

Als u een bestandsprojectie wilt definiëren, gebruikt files u de matrix in de eigenschap projections.

De bron is altijd /document/normalized_images/* . Bestandsprojecties werken alleen op de normalized_images verzameling. Indexeerders en vaardighedensets worden niet door de oorspronkelijke niet-genormaliseerde afbeelding heen gebracht.

Het doel is altijd een blobcontainer met het mapprefix van de met Base64 gecodeerde waarde van de document-id. Bestandsprojecties kunnen niet dezelfde container delen als objectprojecties en moeten worden geprojecteerd in een andere container.

In het volgende voorbeeld worden alle genormaliseerde afbeeldingen die zijn geëxtraheerd uit het document-knooppunt van een verrijkt document, naar een container met de naam myImages projecten.

"knowledgeStore" : {
    "storageConnectionString": "DefaultEndpointsProtocol=https;AccountName=<Acct Name>;AccountKey=<Acct Key>;",
    "projections": [
        {
            "tables": [ ],
            "objects": [ ],
            "files": [
                {
                    "storageContainer": "myImages",
                    "source": "/document/normalized_images/*"
                }
            ]
        }
    ]
}

Projecteren naar meerdere typen

Voor een complexer scenario moet u mogelijk inhoud projecteren tussen projectietypen. Bijvoorbeeld het projecteren van sleuteltermen en entiteiten naar tabellen, het opslaan van OCR-resultaten van tekst en lay-outtekst als objecten en het projecteren van de afbeeldingen als bestanden.

Stappen voor meerdere projectietypen:

  1. Maak een tabel met een rij voor elk document.
  2. Maak een tabel die is gerelateerd aan de documenttabel met elke sleutelterm die is geïdentificeerd als een rij in deze tabel.
  3. Maak een tabel die is gerelateerd aan de documenttabel met elke entiteit die is geïdentificeerd als een rij in deze tabel.
  4. Maak een objectprojectie met de indelingstekst voor elke afbeelding.
  5. Maak een bestandsprojectie, die elke geëxtraheerde afbeelding projecteert.
  6. Maak een tabel met kruisverwijzingen die verwijzingen bevat naar de documenttabel, objectprojectie met de indelingstekst en de bestandsprojectie.

Gegevens vormgeven voor kruisprojectie

Om de vormen te krijgen die nodig zijn voor deze projecties, begint u met het toevoegen van een nieuwe Shaper-vaardigheid die een vormgegeven object met de naam crossProjection maakt.

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

Tabel-, object- en bestandsprojecties definiëren

Slice vanuit het geconsolideerde object crossProjection het object in meerdere tabellen, leg de OCR-uitvoer vast als blobs en sla de afbeelding vervolgens op als bestanden (ook in Blob Storage).

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

Objectprojecties vereisen een containernaam voor elke projectie. Objectprojecties en bestandsprojecties kunnen geen container delen.

Relaties tussen tabel-, object- en bestandsprojecties

In dit voorbeeld wordt ook een andere functie van projecties belicht. Door meerdere typen projecties binnen hetzelfde projectieobject te definiëren, wordt er een relatie uitgedrukt binnen en tussen de verschillende typen (tabellen, objecten, bestanden). Hiermee kunt u beginnen met een tabelrij voor een document en alle OCR-tekst voor de afbeeldingen in dat document in de objectprojectie zoeken.

Als u de gegevens niet wilt gerelateerd, definieert u de projecties in verschillende projectiegroepen. Het volgende fragment resulteert er bijvoorbeeld in dat de tabellen gerelateerd zijn, maar zonder relaties tussen de tabellen en de objectprojecties (OCR-tekst).

Projectiegroepen zijn handig wanneer u dezelfde gegevens in verschillende vormen wilt projecteren voor verschillende behoeften. Bijvoorbeeld een projectiegroep voor het Power BI-dashboard en een andere projectiegroep voor het vastleggen van gegevens die worden gebruikt om een machine learning-model te trainen dat is verpakt in een aangepaste vaardigheid.

Bij het bouwen van projecties van verschillende typen worden eerst bestands- en objectprojecties gegenereerd en worden de paden toegevoegd aan de tabellen.

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

Volgende stappen

In het voorbeeld in dit artikel worden algemene patronen getoond voor het maken van projecties. Nu u een goed begrip van de concepten hebt, bent u beter uitgerust om projecties te bouwen voor uw specifieke scenario.