Detaljerat exempel på former och projektioner i ett kunskapslager

Den här artikeln innehåller ett detaljerat exempel som kompletterar avancerade begrepp och syntaxbaserade artiklar genom att gå igenom de steg för formning och projektion som krävs för att helt uttrycka resultatet av en omfattande kunskapsuppsättning i ett kunskapslager.

Om dina programkrav kräver flera färdigheter och projektioner kan det här exemplet ge dig en bättre uppfattning om hur former och projektioner överser varandra.

Ladda ned exempeldefinitioner

I det här exemplet används Postman Desktop-programmet och REST-API:erna Search.

Klona eller ladda ned azure-search-postman-samples på GitHub importera samlingen Projektioner för att gå igenom det här exemplet själv.

Konfigurera exempeldata

Exempeldokument ingår inte specifikt i samlingen Projektioner, men AI-berikningsdemodatafilerna från lagringsplatsen azure-search-sample-data innehåller text och bilder och fungerar med de projektioner som beskrivs i det här exemplet.

Skapa en blobcontainer i Azure Storage ladda upp alla 14 objekt.

När du Azure Storage kopierar du en anslutningssträng så att du kan ange den i Postman-samlingen.

Exempel på kompetensuppsättning

Om du vill förstå beroendet mellan former och projektioner kan du granska följande kunskapsuppsättning som skapar berikat innehåll. Den här kunskapsuppsättningen bearbetar både rådatabilder och text, vilket producerar utdata som refereras till i former och projektioner.

Var uppmärksam på kunskapsutdata (targetNames). Utdata som skrivs till det berikade dokumentträdet refereras i projektioner och i former (via Shaper-kunskaper).

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

Exempel på Formarfärdighet

En Formarfärdighet är ett verktyg för att arbeta med befintligt berikat innehåll i stället för att skapa nytt berikat innehåll. Genom att lägga till en Formare i en kunskapsuppsättning kan du skapa en anpassad form som du kan projicera till tabell- eller bloblagring. Utan en anpassad form är projektioner begränsade till att referera till en enskild nod (en projektion per utdata), vilket inte är lämpligt för tabeller. När du skapar en anpassad form aggregeras olika element i en ny logisk helhet som kan projiceras som en enskild tabell, eller segmenteras och distribueras i en samling tabeller.

I det här exemplet kombinerar den anpassade formen blobmetadata och identifierade entiteter och nyckelfraser. Den anpassade formen anropas projectionShape och är överordnad under /document .

Ett syfte med att forma är att se till att alla berikningsnoder uttrycks i välformformad JSON, vilket krävs för att projicera till kunskapslager. Detta gäller särskilt när ett berikande träd innehåller noder som inte är välformade JSON (till exempel när en berikning är överordnad en primitiv som en sträng).

Lägg märke till de två sista KeyPhrases noderna, och Entities . Dessa omsluts i ett giltigt JSON-objekt med sourceContext . Detta krävs när och berikas på primitiver och måste konverteras till keyphrases entities giltig JSON innan de kan projiceras.

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

Lägga till formare i en kunskapsuppsättning

Exempelkunskapsuppsättningen som introducerades i början av den här artikeln innehåller inte Shaper-färdigheten, men Shaper-kunskaperna tillhör en kompetensuppsättning och placeras ofta i slutet.

I en kompetensuppsättning kan en Formarfärdighet se ut så här:

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

Projicera till tabeller

När du ritar på exemplen ovan finns det en känd mängd berikande och dataformer som kan refereras till i tabellprojektioner. I tabellprojektionen nedan definieras tre tabeller genom att egenskaperna tableName och source generatedKeyName anges.

Alla tre tabellerna är relaterade via genererade nycklar och av den delade överordnade /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": []
        }
    ]
}

Testa ditt arbete

Du kan kontrollera projektionsdefinitioner genom att följa dessa steg:

  1. Ange egenskapen för kunskapslagret till storageConnectionString en giltig anslutningssträng för V2-lagringskontot för generell användning.

  2. Uppdatera kompetensuppsättningen genom att utfärda PUT-begäran.

  3. När du har uppdaterat kunskapsuppsättningen kör du indexeraren.

Nu har du en fungerande projektion med tre tabeller. Om du importerar dessa Power BI till en Power BI att relationerna upptäcks automatiskt.

Innan vi går vidare till nästa exempel ska vi gå tillbaka till aspekter av tabellprojektionen för att förstå mekanismerna för att skapa och relatera data.

Slicera en tabell till flera underordnade tabeller

Utdelning är en teknik som delar in en hel konsoliderad form i komponenter. Resultatet består av separata men relaterade tabeller som du kan arbeta med individuellt.

I det här exemplet projectionShape är den konsoliderade formen (eller berikningsnoden). I projektionsdefinitionen segmenteras i ytterligare tabeller, vilket gör att du projectionShape kan hämta delar av figuren och keyPhrases Entities . I Power BI är detta användbart eftersom flera entiteter och keyPhrases är associerade med varje dokument, och du får fler insikter om du kan se entiteter och keyPhrases som kategoriserade data.

Med implicit utkring genereras en relation mellan de överordnade och underordnade tabellerna, med hjälp av i den överordnade tabellen för att skapa en kolumn med samma namn i generatedKeyName den underordnade tabellen.

Namnge relationer

Egenskaperna generatedKeyName och används för att relatera data mellan tabeller eller till och med mellan referenceKeyName projektionstyper. Varje rad i den underordnade tabellen har en egenskap som pekar tillbaka till den överordnade tabellen. Namnet på kolumnen eller egenskapen i den underordnade är från referenceKeyName den överordnade. När referenceKeyName inte har angetts används standardvärdet från generatedKeyName den överordnade tjänsten.

Power BI dessa genererade nycklar för att identifiera relationer i tabellerna. Om du behöver kolumnen i den underordnade tabellen med olika namn anger du referenceKeyName egenskapen för den överordnade tabellen. Ett exempel är att ange generatedKeyName som ID i tblDocument-tabellen och referenceKeyName som DocumentID. Detta resulterar i kolumnen i tabellerna tblEntities och tblKeyPhrases som innehåller dokument-ID:t som heter DocumentID.

Projicera blobdokument

Objektprojektioner är JSON-representationer av berikande träd som kan kommas från valfri nod. I jämförelse med tabellprojektioner är objektprojektioner enklare att definiera och används när du projicerar hela dokument. Objektprojektioner är begränsade till en enda projektion i en container och kan inte segmenteras.

Om du vill definiera en objektprojektion använder objects du matrisen i egenskapen projections.

Källan är sökvägen till en nod i berikande träd som är projektionens rot. Även om det inte krävs är nodsökvägen vanligtvis utdata från en Shaper-kunskap. Det beror på att de flesta kunskaper inte matar ut giltiga JSON-objekt på egen hand, vilket innebär att någon form av formning är nödvändig. I många fall kan samma Formarfärdighet som skapar en tabellprojektion användas för att generera en objektprojektion. Alternativt kan källan också anges till en nod med en infogade formning för att tillhandahålla strukturen.

Målet är alltid en blobcontainer.

I följande exempel projekterar vi enskilda hotelldokument, ett hotelldokument per blob, i en container med namnet hotels .

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

Källan är utdata från en Shaper-färdighet med namnet "objectprojection". Varje blob har en JSON-representation av varje fältindata.

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

Projicera en bildfil

Filprojektioner är alltid binära, normaliserade bilder, där normalisering refererar till potentiell storleksändring och rotation för användning vid körning av kunskapsuppsättning. Filprojektioner, som liknar objektprojektioner, skapas som blobar i Azure Storage och innehåller bilden.

Om du vill definiera en filprojektion använder files du matrisen i egenskapen projections.

Källan är alltid /document/normalized_images/* . Filprojektioner fungerar bara på normalized_images samlingen. Varken indexerare eller en kunskapsuppsättning passerar genom den ursprungliga icke-normaliserade bilden.

Målet är alltid en blobcontainer med mappprefixet för det base64-kodade värdet för dokument-ID:t. Filprojektioner kan inte dela samma container som objektprojektioner och måste projiceras till en annan container.

I följande exempel projekteras alla normaliserade avbildningar som extraheras från dokumentnoden i ett berikat dokument till en container med namnet myImages .

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

Projicera till flera typer

Ett mer komplext scenario kan kräva att du projicerar innehåll mellan projektionstyper. Du kan till exempel projicera nyckelfraser och entiteter till tabeller, spara OCR-resultat av text och layouttext som objekt och sedan projicera bilderna som filer.

Steg för flera projektionstyper:

  1. Skapa en tabell med en rad för varje dokument.
  2. Skapa en tabell relaterad till dokumenttabellen med varje nyckelfras som identifieras som en rad i den här tabellen.
  3. Skapa en tabell som är relaterad till dokumenttabellen med varje entitet som identifieras som en rad i den här tabellen.
  4. Skapa en objektprojektion med layouttexten för varje bild.
  5. Skapa en filprojektion som projicerar varje extraherad bild.
  6. Skapa en korsreferenstabell som innehåller referenser till dokumenttabellen, objektprojektion med layouttexten och filprojektionen.

Forma data för korsprojektion

För att få de former som behövs för dessa projektioner börjar du med att lägga till en ny Formarfärdighet som skapar ett format objekt med namnet 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"
        }
    ]
}

Definiera tabell-, objekt- och filprojektioner

Från det konsoliderade crossProjection-objektet segmentar du objektet i flera tabeller, avbildar OCR-utdata som blobar och sparar sedan bilden som filer (även i 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"
                }
            ]
        }
    ]
}

Objektprojektioner kräver ett containernamn för varje projektion. Objektprojektioner och filprojektioner kan inte dela en container.

Relationer mellan tabell-, objekt- och filprojektioner

Det här exemplet visar också en annan funktion i projektioner. Genom att definiera flera typer av projektioner i samma projektionsobjekt finns det en relation som uttrycks inom och över de olika typerna (tabeller, objekt, filer). På så sätt kan du börja med en tabellrad för ett dokument och hitta all OCR-text för bilderna i dokumentet i objektprojektionen.

Om du inte vill att data ska vara relaterade definierar du projektionerna i olika projektionsgrupper. Följande kodfragment resulterar till exempel i att tabellerna är relaterade, men utan relationer mellan tabellerna och objektprojektionerna (OCR-text).

Projektionsgrupper är användbara när du vill projicera samma data i olika former för olika behov. Till exempel en projektionsgrupp för Power BI instrumentpanel och en annan projektionsgrupp för att samla in data som används för att träna en maskininlärningsmodell som är omsluten i en anpassad färdighet.

När du skapar projektioner av olika typer genereras först fil- och objektprojektioner, och sökvägarna läggs till i tabellerna.

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

Nästa steg

Exemplet i den här artikeln visar vanliga mönster för hur du skapar projektioner. Nu när du har en god förståelse för begreppen är du bättre på att skapa projektioner för ditt specifika scenario.