Szczegółowy przykład kształtów i projekcji w magazynie wiedzy

Ten artykuł zawiera szczegółowy przykład, który uzupełnia koncepcje wysokiego poziomu i artykuły oparte na składni, przechodząc przez kroki kształtowania i projekcji wymagane do pełnego wyrażenia danych wyjściowych rozbudowanego zestawu umiejętności w magazynie wiedzy.

Jeśli wymagania dotyczące aplikacji wymagają wielu umiejętności i projekcji, ten przykład może dać lepszy obraz sposobu, w jaki kształty i projekcje przecinają się.

Pobieranie przykładowych definicji

W tym przykładzie użyto aplikacji klasycznej Postman i interfejsów API REST wyszukiwania.

Sklonuj lub pobierz plik azure-search-postman-samples na stronie GitHub i zaimportuj kolekcję Projekcje, aby samodzielnie przejść przez ten przykład.

Kopiowanie przykładowych danych

Przykładowe dokumenty nie są specjalnie dołączone do kolekcji Projekcje, ale pliki danych demonstracyjnych wzbogacania OI z usługi azure-search-sample-data zawierają tekst i obrazy i będą działać z projekcjami opisanymi w tym przykładzie.

Utwórz kontener obiektów blob w usłudze Azure Storage i przekaż wszystkie 14 elementów.

W usłudze Azure Storage skopiuj ciąg połączenia, aby można je było określić w kolekcji Postman.

Przykładowy umiejętności

Aby zrozumieć zależność między kształtami i projekcjami, zapoznaj się z następującymi umiejętnościami, który tworzy wzbogaconą zawartość. Ten umiejętności przetwarza zarówno nieprzetworzone obrazy, jak i tekst, tworząc dane wyjściowe, do których będą się odwoływać kształty i projekcje.

Zwróć szczególną uwagę na dane wyjściowe umiejętności (targetNames). Dane wyjściowe zapisywane w wzbogaconym drzewie dokumentów są przywołyowane w projekcjach i kształtach (za pośrednictwem umiejętności kształtowania).

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

Przykład umiejętności kształtowania

Umiejętność Kształtowanie to narzędzie do pracy z istniejącą wzbogaconą zawartością zamiast tworzenia nowej wzbogaconej zawartości. Dodanie kształtowania do zestawu umiejętności umożliwia utworzenie niestandardowego kształtu, który można rzutować na magazyn tabel lub obiektów blob. Bez niestandardowego kształtu projekcje są ograniczone do odwoływania się do jednego węzła (jeden rzut na wyjście), który nie jest odpowiedni dla tabel. Utworzenie kształtu niestandardowego agreguje różne elementy w nową logiczną całość, która może być rzutowana jako pojedyncza tabela lub fragmentowana i dystrybuowana w kolekcji tabel.

W tym przykładzie kształt niestandardowy łączy metadane obiektu blob oraz zidentyfikowane jednostki i frazy kluczowe. Niestandardowy kształt jest wywoływany projectionShape i jest nadrzędny w obszarze /document .

Jednym z celów kształtowania jest zapewnienie, że wszystkie węzły wzbogacania są wyrażone w dobrze uformowanych danych JSON, które są wymagane do rzutowania do magazynu wiedzy. Dzieje się tak szczególnie wtedy, gdy drzewo wzbogacania zawiera węzły, które nie są dobrze uformowane w formacie JSON (na przykład gdy wzbogacanie jest nadrzędne do prymitywu, takiego jak ciąg).

Zwróć uwagę na dwa ostatnie węzły: KeyPhrases i Entities . Są one opakowane w prawidłowy obiekt JSON za pomocą obiektu sourceContext . Jest to wymagane jako i są wzbogaceniami w typach pierwotnych i muszą zostać przekonwertowane na prawidłowy kod JSON, zanim będzie keyphrases można je entities prognozować.

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

Dodawanie kształtowania do umiejętności

Przykładowy umiejętności wprowadzony na początku tego artykułu nie zawierał umiejętności Kształtowanie, ale umiejętności kształtowania należą do grupy umiejętności i często są umieszczane pod koniec.

W ramach umiejętności umiejętność Kształtowanie może wyglądać tak:

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

Rzutowanie na tabele

Na podstawie powyższych przykładów istnieje znana ilość wzbogaceń i kształtów danych, do których można się odwoływać w projekcjach tabeli. W projekcji tabel poniżej trzy tabele są definiowane przez ustawienie tableName właściwości , source i generatedKeyName .

Wszystkie trzy z tych tabel będą powiązane za pośrednictwem wygenerowanych kluczy i udostępnionego elementu nadrzędnego /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": []
        }
    ]
}

Testowanie pracy

Definicje projekcji można sprawdzić, wykonać następujące kroki:

  1. Ustaw właściwość magazynu wiedzy na prawidłowe ciągi połączenia konta magazynu ogólnego przeznaczenia w wersji storageConnectionString 2.

  2. Zaktualizuj umiejętności, wydając żądanie PUT.

  3. Po zaktualizowaniu umiejętności uruchom indeksator.

Masz teraz projekcję roboczą z trzema tabelami. Zaimportowanie tych tabel do Power BI powinno spowodować Power BI automatyczne odnajdowanie relacji.

Przed przejściem do następnego przykładu wróćmy do aspektów projekcji tabeli, aby zrozumieć mechanikę cowania i powiązyania danych.

Slicing a table into multiple child tables (Likowanie tabeli na wiele tabel podrzędnych)

Fragmentowanie to technika, która pozwala ująć cały skonsolidowany kształt w części składowe. Wynik składa się z oddzielnych, ale powiązanych tabel, z których można pracować indywidualnie.

W tym przykładzie projectionShape jest to skonsolidowany kształt (lub węzeł wzbogacania). W definicji projekcji element jest fragmentowany na dodatkowe tabele, co umożliwia ściągnięcie projectionShape części kształtu keyPhrases i Entities . W Power BI jest to przydatne, ponieważ z każdym dokumentem jest skojarzonych wiele jednostek i fraz keyPhrases, a jeśli zobaczysz jednostki i frazy keyPhrases jako dane skategoryzowane, otrzymasz więcej szczegółowych informacji.

Tworzenie nacjeń niejawnie generuje relację między tabelami nadrzędnymi i podrzędnym przy użyciu elementu w tabeli nadrzędnej w celu utworzenia kolumny o tej samej nazwie w generatedKeyName tabeli podrzędnej.

Nazewnictwo relacji

Właściwości generatedKeyName i są używane do referenceKeyName powiązać dane między tabelami, a nawet między typami projekcji. Każdy wiersz w tabeli podrzędnej ma właściwość, która jest z powrotem wskazują obiekt nadrzędny. Nazwa kolumny lub właściwości w obiekcie podrzędnym pochodzi referenceKeyName od elementu nadrzędnego. Jeśli obiekt nie zostanie podany, usługa domyślnie go referenceKeyName z elementu generatedKeyName nadrzędnego.

Power BI korzysta z tych wygenerowanych kluczy w celu odnajdywania relacji w tabelach. Jeśli potrzebujesz kolumny w tabeli podrzędnej o innej nazwie, ustaw referenceKeyName właściwość w tabeli nadrzędnej. Przykładem może być ustawienie jako generatedKeyName identyfikatora w tabeli tblDocument i jako referenceKeyName identyfikatora documentID. Spowoduje to kolumnę w tabelach tblEntities i tblKeyPhrases zawierającą identyfikator dokumentu o nazwie DocumentID.

Rzutowanie dokumentów obiektów blob

Projekcje obiektów to reprezentacje JSON drzewa wzbogacania, które mogą być źródłem z dowolnego węzła. W porównaniu z projekcjami tabeli projekcje obiektów są prostsze do zdefiniowania i są używane podczas projekcji całych dokumentów. Projekcje obiektów są ograniczone do pojedynczego projekcji w kontenerze i nie można ich fragmentować.

Aby zdefiniować projekcję obiektu, użyj objects tablicy we właściwości projections.

Źródło jest ścieżką do węzła drzewa wzbogacania, który jest katalogami głównymi projekcji. Chociaż nie jest to wymagane, ścieżka węzła jest zwykle wyjściem umiejętności kształtowania. Wynika to z tego, że większość umiejętności nie wyprowadza prawidłowych obiektów JSON samodzielnie, co oznacza, że konieczna jest jakaś forma kształtowania. W wielu przypadkach do wygenerowania projekcji obiektu można użyć tej samej umiejętności kształtowania, która tworzy projekcję tabeli. Alternatywnie źródło można również ustawić na węzeł z kształtowaniem w tekście w celu zapewnienia struktury.

Miejsce docelowe jest zawsze kontenerem obiektów blob.

W poniższym przykładzie projektuje pojedyncze dokumenty hotelowe, jeden dokument hotelowy na obiekt blob, w kontenerze o nazwie hotels .

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

Źródłem są dane wyjściowe umiejętności kształtowania o nazwie "objectprojection". Każdy obiekt blob będzie miał reprezentację JSON poszczególnych danych wejściowych pola.

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

Rzutowanie pliku obrazu

Projekcje plików są zawsze obrazami binarnymi, znormalizowane, gdzie normalizacja odnosi się do potencjalnej zmiany rozmiaru i rotacji do użycia w wykonywaniu pakietu umiejętności. Projekcje plików, podobnie jak projekcje obiektów, są tworzone jako obiekty blob w usłudze Azure Storage i zawierają obraz.

Aby zdefiniować projekcję pliku, użyj files tablicy we właściwości projections.

Źródłem jest zawsze /document/normalized_images/* . Projekcje plików działają tylko na normalized_images kolekcji. Ani indeksatorzy, ani indeksatorzy nie przejdą przez oryginalny nieznormalizowany obraz.

Miejsce docelowe jest zawsze kontenerem obiektów blob z prefiksem folderu zakodowanej w formacie base64 wartości identyfikatora dokumentu. Projekcje plików nie mogą współużytkować tego samego kontenera co projekcje obiektów i muszą być rzutowane na inny kontener.

Poniższy przykład przedstawia projekty wszystkich znormalizowanych obrazów wyodrębnianych z węzła dokumentu wzbogaconego dokumentu do kontenera o nazwie myImages .

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

Rzutowanie na wiele typów

Bardziej złożony scenariusz może wymagać projekcji zawartości dla różnych typów projekcji. Na przykład rzutowanie kluczowych fraz i jednostek na tabele, zapisywanie wyników OCR tekstu i tekstu układu jako obiektów, a następnie rzutowanie obrazów jako plików.

Kroki dla wielu typów projekcji:

  1. Utwórz tabelę z wierszem dla każdego dokumentu.
  2. Utwórz tabelę powiązaną z tabelą dokumentów z każdą frazą kluczową identyfikowaną jako wiersz w tej tabeli.
  3. Utwórz tabelę powiązaną z tabelą dokumentów z każdą jednostką identyfikowaną jako wiersz w tej tabeli.
  4. Utwórz projekcję obiektu z tekstem układu dla każdego obrazu.
  5. Utwórz projekcję pliku, rzutując każdy wyodrębniony obraz.
  6. Utwórz tabelę odsyłaczy zawierającą odwołania do tabeli dokumentów, projekcję obiektu z tekstem układu i projekcję pliku.

Kształtowanie danych w celu projekcji krzyżowej

Aby uzyskać kształty potrzebne do tych projekcji, zacznij od dodania nowej umiejętności Kształtowanie, która tworzy ukształtowany obiekt o nazwie 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"
        }
    ]
}

Definiowanie projekcji tabeli, obiektu i pliku

Ze skonsolidowanego obiektu crossProjection należy go rozłożyć na wiele tabel, przechwycić dane wyjściowe OCR jako obiekty blob, a następnie zapisać obraz jako pliki (również w magazynie obiektów 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"
                }
            ]
        }
    ]
}

Projekcje obiektów wymagają nazwy kontenera dla każdego projekcji. Projekcje obiektów i projekcje plików nie mogą współdzielić kontenera.

Relacje między projekcjami tabeli, obiektu i pliku

W tym przykładzie wyróżniona została również inna funkcja projekcji. Definiując wiele typów projekcji w ramach tego samego obiektu projekcji, istnieje relacja wyrażona wewnątrz i między różnymi typami (tabelami, obiektami, plikami). Dzięki temu można rozpocząć od wiersza tabeli dla dokumentu i znaleźć cały tekst OCR dla obrazów w tym dokumencie w projekcji obiektu.

Jeśli nie chcesz, aby dane były powiązane, zdefiniuj projekcje w różnych grupach projekcji. Na przykład poniższy fragment kodu spowoduje, że tabele będą powiązane, ale bez relacji między tabelami i projekcjami obiektu (tekst OCR).

Grupy projekcji są przydatne, gdy chcesz projektować te same dane w różnych kształtach dla różnych potrzeb. Na przykład grupa projekcji dla pulpitu Power BI nawigacyjnego i inna grupa projekcji do przechwytywania danych używanych do trenowania modelu uczenia maszynowego opakowanego w niestandardową umiejętność.

Podczas tworzenia projekcji różnych typów najpierw są generowane projekcje plików i obiektów, a ścieżki są dodawane do tabel.

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

Następne kroki

W przykładzie w tym artykule pokazano typowe wzorce tworzenia projekcji. Teraz, gdy dobrze rozumiesz pojęcia, możesz lepiej tworzyć projekcje dla konkretnego scenariusza.