Kurz: Použití rozhraní .NET a AI k vygenerování prohledávatelného obsahu z objektů blob Azure

Pokud máte v Azure Blob Storage nestrukturovaný text nebo obrázky, může kanál rozšiřování umělé inteligence extrahovat informace a vytvořit nový obsah pro scénáře fulltextového vyhledávání nebo dolování znalostí.

V tomto kurzu jazyka C# se naučíte:

  • Nastavte vývojové prostředí.
  • Definujte kanál, který používá rozpoznávání jazyka, rozpoznávání entit a extrakci klíčových frází.
  • Spusťte kanál pro vyvolání transformací a vytvoření a načtení indexu vyhledávání.
  • Prozkoumejte výsledky pomocí fulltextového vyhledávání a syntaxe dotazů s formátováním.

Pokud nemáte předplatné Azure, otevřete si před zahájením bezplatný účet .

Přehled

Tento kurz používá jazyk C# a klientskou knihovnu Azure.Search.Documents k vytvoření zdroje dat, indexu, indexeru a sady dovedností.

Indexer se připojí k ukázkovým datům v kontejneru objektů blob, který je zadaný v objektu zdroje dat, a odešle veškerý obohacený obsah do indexu vyhledávání.

Sada dovedností je připojena k indexeru. K vyhledání a extrahování informací využívá integrované dovednosti od Microsoftu. Mezi kroky v kanálu patří optické rozpoznávání znaků (OCR) u obrázků, rozpoznávání jazyka u textu, extrakce klíčových frází a rozpoznávání entit (organizace). Nové informace vytvořené kanálem se ukládají do nových polí v indexu. Po naplnění indexu můžete pole použít v dotazech, omezujících vlastnostech a filtrech.

Požadavky

Poznámka

Pro účely tohoto kurzu můžete použít bezplatnou vyhledávací službu. Bezplatná vyhledávací služba vás omezuje na tři indexy, tři indexery a tři zdroje dat. V tomto kurzu se vytváří od každého jeden. Než začnete, ujistěte se, že máte ve službě místo pro přijetí nových prostředků.

Stažení souborů

Ukázková data se skládají ze 14 souborů smíšeného obsahu, které v pozdějším kroku nahrajete do služby Azure Blob Storage.

  1. Získejte soubory z azure-search-sample-data/ai-enrichment-mixed-media/ a zkopírujte je do místního počítače.

  2. Dále získejte zdrojový kód pro tento kurz. Zdrojový kód je ve složce tutorial-ai-enrichment/v11 v úložišti azure-search-dotnet-samples .

1. Vytvoření služeb

Tento kurz používá Azure Cognitive Search k indexování a dotazům, službám Cognitive Services na back-endu pro rozšiřování AI a azure Blob Storage k poskytování dat. Tento kurz zůstává v rámci bezplatného přidělování 20 transakcí na indexer za den ve službách Cognitive Services, takže jedinými službami, které potřebujete vytvořit, jsou vyhledávání a úložiště.

Pokud je to možné, vytvořte obě ve stejné oblasti a skupině prostředků pro blízkost a správu. V praxi může být váš účet Azure Storage v libovolné oblasti.

Začínáme se službou Azure Storage

  1. Přihlaste se k webu Azure Portal a klikněte na + Vytvořit prostředek.

  2. Vyhledejte účet úložiště a vyberte nabídku účtu úložiště Microsoftu.

    Create Storage account

  3. Na kartě Základy jsou vyžadovány následující položky. Přijměte výchozí hodnoty pro všechno ostatní.

    • Skupina prostředků. Vyberte existující nebo vytvořte novou, ale použijte stejnou skupinu pro všechny služby, abyste je mohli spravovat souhrnně.

    • Název účtu úložiště: Pokud si myslíte, že máte více prostředků stejného typu, použijte název k nejednoznačnosti podle typu a oblasti, například blobstoragewestus.

    • Umístění: Pokud je to možné, zvolte stejné umístění, které se používá pro Azure Cognitive Search a Cognitive Services. Poplatky za šířku pásma na jednom místě jsou neplatné.

    • Druh účtu. Zvolte výchozí hodnotu StorageV2 (pro obecné účely v2).

  4. Vyberte Zkontrolovat a vytvořit službu.

  5. Po vytvoření vyberte Přejít k prostředku a otevřete stránku Přehled.

  6. Vyberte službu Blobs Service.

  7. Výběrem + Kontejner vytvořte kontejner a pojmenujte ho cog-search-demo.

  8. Vyberte ukázku ozubeného kolečka a pak výběrem možnosti Nahrát otevřete složku, do které jste uložili soubory pro stahování. Vyberte všechny soubory. Vyberte Nahrát.

    Screenshot of the files in File Explorer.

  9. Než opustíte Azure Storage, získejte připojovací řetězec, abyste mohli formulovat připojení ve službě Azure Cognitive Search.

    1. Vraťte se na stránku Přehled vašeho účtu úložiště (jako příklad jsme použili blobstragewestus ).

    2. V levém navigačním podokně vyberte Přístupové klávesy a zkopírujte jeden z připojovacích řetězců.

    Připojovací řetězec je adresa URL podobná následujícímu příkladu:

    DefaultEndpointsProtocol=https;AccountName=cogsrchdemostorage;AccountKey=<your account key>;EndpointSuffix=core.windows.net
    
  10. Uložte připojovací řetězec do Poznámkového bloku. Budete ho potřebovat později při nastavování připojení ke zdroji dat.

Cognitive Services

Rozšiřování umělé inteligence je podporováno službami Cognitive Services, včetně služeb jazyka a počítačového zpracování obrazu pro přirozený jazyk a zpracování obrázků. Pokud vaším cílem bylo dokončit skutečný prototyp nebo projekt, zřídili byste v tomto okamžiku služby Cognitive Services (ve stejné oblasti jako Azure Cognitive Search), abyste ho mohli připojit k operacím indexování.

V tomto cvičení ale můžete přeskočit zřizování prostředků, protože Azure Cognitive Search se může připojit ke službám Cognitive Services na pozadí a poskytnout 20 bezplatných transakcí na spuštění indexeru. Vzhledem k tomu, že tento kurz používá 14 transakcí, je volné přidělení dostatečné. U větších projektů naplánujte zřizování služeb Cognitive Services na úrovni S0 s průběžným platbou. Další informace najdete v tématu Připojení služeb Cognitive Services.

Třetí komponentou je Azure Cognitive Search, kterou můžete vytvořit na portálu nebo najít existující vyhledávací službu ve vašem předplatném.

K dokončení tohoto návodu můžete použít úroveň Free.

K interakci se službou Azure Cognitive Search budete potřebovat adresu URL služby a přístupový klíč.

  1. Přihlaste se k webu Azure Portal a na stránce Přehled vyhledávací služby získejte název vyhledávací služby. Název služby můžete potvrdit kontrolou adresy URL koncového bodu. Pokud by adresa URL vašeho koncového bodu byla https://mydemo.search.windows.net, název vaší služby by byl mydemo.

  2. V části Klíče nastavení> získejte klíč správce pro úplná práva ve službě. Primární nebo sekundární klíč můžete zkopírovat.

Get the service name and admin key

Platný klíč vytváří na základě žádosti vztah důvěryhodnosti mezi aplikací, která žádost odeslala, a službou, která ji zpracovává.

2. Nastavení prostředí

Začněte otevřením sady Visual Studio a vytvořením nového projektu konzolové aplikace, který může běžet v .NET Core.

Instalace Azure.Search.Documents

Sada .NET SDK služby Azure Cognitive Search se skládá z klientské knihovny, která umožňuje spravovat indexy, zdroje dat, indexery a sady dovedností a také nahrávat a spravovat dokumenty a spouštět dotazy, aniž byste museli zpracovávat podrobnosti protokolu HTTP a JSON. Tato klientská knihovna je distribuovaná jako balíček NuGet.

Pro tento projekt nainstalujte verzi 11 nebo novější Azure.Search.Documents a nejnovější verzi Microsoft.Extensions.Configuration.

  1. V sadě Visual Studio vyberte Nástroje> Správce >balíčků NuGetspravovat balíčky NuGet pro řešení...

  2. Vyhledejte Azure.Search.Document.

  3. Vyberte nejnovější verzi a klikněte na Nainstalovat.

  4. Opakováním předchozích kroků nainstalujte Microsoft.Extensions.Configuration a Microsoft.Extensions.Configuration.Json.

Přidání informací o připojení ke službě

  1. V Průzkumníku řešení klikněte pravým tlačítkem myši na projekt a vyberte Přidat>novou položku... .

  2. Pojmenujte soubor appsettings.json a vyberte Přidat.

  3. Tento soubor zahrňte do výstupního adresáře.

    1. Klikněte pravým tlačítkem myši a appsettings.json vyberte Vlastnosti.
    2. Pokud je novější, změňte hodnotu kopírovat do výstupního adresáře.
  4. Zkopírujte následující JSON do nového souboru JSON.

    {
      "SearchServiceUri": "Put your search service URI here",
      "SearchServiceAdminApiKey": "Put your primary or secondary API key here",
      "SearchServiceQueryApiKey": "Put your query API key here",
      "AzureBlobConnectionString": "Put your Azure Blob connection string here",
    }
    

Přidejte informace o účtu úložiště objektů blob a vyhledávací služby. Vzpomeňte si, že tyto informace můžete získat z kroků zřizování služeb uvedených v předchozí části.

Do pole SearchServiceUri zadejte úplnou adresu URL.

Přidání oborů názvů

Do Program.cspole přidejte následující obory názvů.

using Azure;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;

namespace EnrichwithAI

Vytvoření klienta

Vytvořte instanci objektu SearchIndexClient a pod Mainpoložkou SearchIndexerClient .

public static void Main(string[] args)
{
    // Create service client
    IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
    IConfigurationRoot configuration = builder.Build();

    string searchServiceUri = configuration["SearchServiceUri"];
    string adminApiKey = configuration["SearchServiceAdminApiKey"];
    string cognitiveServicesKey = configuration["CognitiveServicesKey"];

    SearchIndexClient indexClient = new SearchIndexClient(new Uri(searchServiceUri), new AzureKeyCredential(adminApiKey));
    SearchIndexerClient indexerClient = new SearchIndexerClient(new Uri(searchServiceUri), new AzureKeyCredential(adminApiKey));
}

Poznámka

Klienti se připojují k vyhledávací službě. Abyste se vyhnuli otevření příliš velkého počtu připojení, měli byste se v případě potřeby pokusit sdílet jednu instanci ve vaší aplikaci. Tyto metody jsou bezpečné pro sdílení vláken.

Přidání funkce pro ukončení programu během selhání

Tento kurz vám pomůže porozumět jednotlivým krokům kanálu indexování. Pokud dojde k kritickému problému, který brání programu ve vytváření zdroje dat, sady dovedností, indexu nebo indexeru, program zobrazí chybovou zprávu a ukončí, aby problém mohl být srozumitelný a vyřešený.

Přidejte ExitProgram do Main zpracování scénářů, které vyžadují ukončení programu.

private static void ExitProgram(string message)
{
    Console.WriteLine("{0}", message);
    Console.WriteLine("Press any key to exit the program...");
    Console.ReadKey();
    Environment.Exit(0);
}

3. Vytvoření kanálu

Ve službě Azure Cognitive Search probíhá zpracování umělé inteligence během indexování (nebo příjmu dat). Tato část návodu vytvoří čtyři objekty: zdroj dat, definici indexu, sadu dovedností, indexer.

Krok 1: Vytvoření zdroje dat

SearchIndexerClientDataSourceName má vlastnost, kterou můžete nastavit na SearchIndexerDataSourceConnection objekt. Tento objekt poskytuje všechny metody, které potřebujete k vytvoření, výpisu, aktualizaci nebo odstranění zdrojů dat Azure Cognitive Search.

Vytvořte novou SearchIndexerDataSourceConnection instanci voláním indexerClient.CreateOrUpdateDataSourceConnection(dataSource). Následující kód vytvoří zdroj dat typu AzureBlob.

private static SearchIndexerDataSourceConnection CreateOrUpdateDataSource(SearchIndexerClient indexerClient, IConfigurationRoot configuration)
{
    SearchIndexerDataSourceConnection dataSource = new SearchIndexerDataSourceConnection(
        name: "demodata",
        type: SearchIndexerDataSourceType.AzureBlob,
        connectionString: configuration["AzureBlobConnectionString"],
        container: new SearchIndexerDataContainer("cog-search-demo"))
    {
        Description = "Demo files to demonstrate cognitive search capabilities."
    };

    // The data source does not need to be deleted if it was already created
    // since we are using the CreateOrUpdate method
    try
    {
        indexerClient.CreateOrUpdateDataSourceConnection(dataSource);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Failed to create or update the data source\n Exception message: {0}\n", ex.Message);
        ExitProgram("Cannot continue without a data source");
    }

    return dataSource;
}

V případě úspěšného požadavku vrátí metoda zdroj dat, který byl vytvořen. Pokud dojde k problému s požadavkem, například neplatný parametr, metoda vyvolá výjimku.

Teď přidejte řádek Main pro volání CreateOrUpdateDataSource funkce, kterou jste právě přidali.

// Create or Update the data source
Console.WriteLine("Creating or updating the data source...");
SearchIndexerDataSourceConnection dataSource = CreateOrUpdateDataSource(indexerClient, configuration);

Sestavte a spusťte řešení. Vzhledem k tomu, že se jedná o váš první požadavek, zkontrolujte web Azure Portal a ověřte, že se zdroj dat vytvořil ve službě Azure Cognitive Search. Na stránce přehledu vyhledávací služby ověřte, že seznam zdrojů dat obsahuje novou položku. Možná bude nutné několik minut počkat, než se stránka portálu aktualizuje.

Data sources tile in the portal

Krok 2: Vytvoření sady dovedností

V této části definujete sadu kroků rozšiřování, které chcete použít pro vaše data. Každý krok rozšiřování se nazývá dovednost a sada kroků rozšiřování, sada dovedností. Tento kurz používá integrované kognitivní dovednosti pro sadu dovedností:

  • Optické rozpoznávání znaků pro rozpoznávání tištěného a ručně psaného textu v souborech obrázků.

  • Sloučení textu pro sloučení textu z kolekce polí do jednoho "sloučeného obsahu" pole.

  • Rozpoznávání jazyka, které identifikuje jazyk obsahu

  • Rozpoznávání entit pro extrahování názvů organizací z obsahu v kontejneru objektů blob

  • Text Split to break large content into menší bloky před voláním dovednosti extrakce klíčových frází a dovednosti rozpoznávání entit. Extrakce klíčových frází a rozpoznávání entit přijímá vstupy o 50 000 znaků nebo méně. Některé ze zdrojových souborů je nutné rozdělit, aby se do tohoto limitu vešly.

  • Extrakce klíčových frází, která získává hlavní klíčové fráze

Během počátečního zpracování azure Cognitive Search prolomí každý dokument a extrahuje obsah z různých formátů souborů. Text pocházející ze zdrojového souboru se umístí do vygenerovaného content pole, jedno pro každý dokument. Proto nastavte vstup tak, aby "/document/content" používal tento text. Obsah obrázku se umístí do vygenerovaného normalized_images pole určeného v sadě dovedností jako /document/normalized_images/*.

Výstupy se dají namapovat na index, použít jako vstup do podřízené dovednosti, nebo využít oběma způsoby tak, jak se to dělá s kódem jazyka. V indexu je kód jazyka užitečný při filtrování. Jako vstup se kód jazyka používá v dovednostech analýzy textu, čímž se jazykovým pravidlům poskytne informace o dělení slov.

Další informace o základních principech sady dovedností najdete v článku o definování sady dovedností.

Dovednost OCR

Extrahuje OcrSkill text z obrázků. Tato dovednost předpokládá, že existuje normalized_images pole. Pokud chcete toto pole vygenerovat, později v kurzu nastavíme "imageAction" konfiguraci v definici indexeru na "generateNormalizedImages".

private static OcrSkill CreateOcrSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("image")
    {
        Source = "/document/normalized_images/*"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("text")
    {
        TargetName = "text"
    });

    OcrSkill ocrSkill = new OcrSkill(inputMappings, outputMappings)
    {
        Description = "Extract text (plain and structured) from image",
        Context = "/document/normalized_images/*",
        DefaultLanguageCode = OcrSkillLanguage.En,
        ShouldDetectOrientation = true
    };

    return ocrSkill;
}

Sloučit dovednosti

V této části vytvoříte MergeSkill , která sloučí pole obsahu dokumentu s textem vytvořeným dovedností OCR.

private static MergeSkill CreateMergeSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("text")
    {
        Source = "/document/content"
    });
    inputMappings.Add(new InputFieldMappingEntry("itemsToInsert")
    {
        Source = "/document/normalized_images/*/text"
    });
    inputMappings.Add(new InputFieldMappingEntry("offsets")
    {
        Source = "/document/normalized_images/*/contentOffset"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("mergedText")
    {
        TargetName = "merged_text"
    });

    MergeSkill mergeSkill = new MergeSkill(inputMappings, outputMappings)
    {
        Description = "Create merged_text which includes all the textual representation of each image inserted at the right location in the content field.",
        Context = "/document",
        InsertPreTag = " ",
        InsertPostTag = " "
    };

    return mergeSkill;
}

Dovednost rozpoznávání jazyka

Rozpozná LanguageDetectionSkill jazyk vstupního textu a nahlásí jeden kód jazyka pro každý dokument odeslaný na žádost. Výstup dovednosti rozpoznávání jazyka použijeme jako součást vstupu do dovednosti Rozdělení textu .

private static LanguageDetectionSkill CreateLanguageDetectionSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("text")
    {
        Source = "/document/merged_text"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("languageCode")
    {
        TargetName = "languageCode"
    });

    LanguageDetectionSkill languageDetectionSkill = new LanguageDetectionSkill(inputMappings, outputMappings)
    {
        Description = "Detect the language used in the document",
        Context = "/document"
    };

    return languageDetectionSkill;
}

Dovednost rozdělení textu

SplitSkill Následující text rozdělí na stránky a omezí délku stránky na 4 000 znaků měřených hodnotou String.Length. Algoritmus se pokusí rozdělit text na bloky, které mají největší maximumPageLength velikost. V tomto případě algoritmus provede nejlepší rozdělení věty na hranici věty, takže velikost bloku může být o něco menší než maximumPageLength.

private static SplitSkill CreateSplitSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("text")
    {
        Source = "/document/merged_text"
    });
    inputMappings.Add(new InputFieldMappingEntry("languageCode")
    {
        Source = "/document/languageCode"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("textItems")
    {
        TargetName = "pages",
    });

    SplitSkill splitSkill = new SplitSkill(inputMappings, outputMappings)
    {
        Description = "Split content into pages",
        Context = "/document",
        TextSplitMode = TextSplitMode.Pages,
        MaximumPageLength = 4000,
        DefaultLanguageCode = SplitSkillLanguage.En
    };

    return splitSkill;
}

Dovednost rozpoznávání entit

Tato EntityRecognitionSkill instance je nastavena na rozpoznávání typu organizationkategorie . Lze EntityRecognitionSkill také rozpoznat typy person kategorií a location.

Všimněte si, že pole "context" je nastaveno na "/document/pages/*" hvězdičku, což znamená, že krok rozšiřování se volá pro každou stránku pod "/document/pages".

private static EntityRecognitionSkill CreateEntityRecognitionSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("text")
    {
        Source = "/document/pages/*"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("organizations")
    {
        TargetName = "organizations"
    });

    EntityRecognitionSkill entityRecognitionSkill = new EntityRecognitionSkill(inputMappings, outputMappings)
    {
        Description = "Recognize organizations",
        Context = "/document/pages/*",
        DefaultLanguageCode = EntityRecognitionSkillLanguage.En
    };
    entityRecognitionSkill.Categories.Add(EntityCategory.Organization);

    return entityRecognitionSkill;
}

Dovednost extrakce klíčových frází

Podobně jako instance EntityRecognitionSkill , která byla právě vytvořena, KeyPhraseExtractionSkill se volá pro každou stránku dokumentu.

private static KeyPhraseExtractionSkill CreateKeyPhraseExtractionSkill()
{
    List<InputFieldMappingEntry> inputMappings = new List<InputFieldMappingEntry>();
    inputMappings.Add(new InputFieldMappingEntry("text")
    {
        Source = "/document/pages/*"
    });
    inputMappings.Add(new InputFieldMappingEntry("languageCode")
    {
        Source = "/document/languageCode"
    });

    List<OutputFieldMappingEntry> outputMappings = new List<OutputFieldMappingEntry>();
    outputMappings.Add(new OutputFieldMappingEntry("keyPhrases")
    {
        TargetName = "keyPhrases"
    });

    KeyPhraseExtractionSkill keyPhraseExtractionSkill = new KeyPhraseExtractionSkill(inputMappings, outputMappings)
    {
        Description = "Extract the key phrases",
        Context = "/document/pages/*",
        DefaultLanguageCode = KeyPhraseExtractionSkillLanguage.En
    };

    return keyPhraseExtractionSkill;
}

Vytvoření a vytvoření sady dovedností

SearchIndexerSkillset Sestavte si dovednosti, které jste vytvořili.

private static SearchIndexerSkillset CreateOrUpdateDemoSkillSet(SearchIndexerClient indexerClient, IList<SearchIndexerSkill> skills,string cognitiveServicesKey)
{
    SearchIndexerSkillset skillset = new SearchIndexerSkillset("demoskillset", skills)
    {
        Description = "Demo skillset",
        CognitiveServicesAccount = new CognitiveServicesAccountKey(cognitiveServicesKey)
    };

    // Create the skillset in your search service.
    // The skillset does not need to be deleted if it was already created
    // since we are using the CreateOrUpdate method
    try
    {
        indexerClient.CreateOrUpdateSkillset(skillset);
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine("Failed to create the skillset\n Exception message: {0}\n", ex.Message);
        ExitProgram("Cannot continue without a skillset");
    }

    return skillset;
}

Přidejte následující řádky do Main.

// Create the skills
Console.WriteLine("Creating the skills...");
OcrSkill ocrSkill = CreateOcrSkill();
MergeSkill mergeSkill = CreateMergeSkill();
EntityRecognitionSkill entityRecognitionSkill = CreateEntityRecognitionSkill();
LanguageDetectionSkill languageDetectionSkill = CreateLanguageDetectionSkill();
SplitSkill splitSkill = CreateSplitSkill();
KeyPhraseExtractionSkill keyPhraseExtractionSkill = CreateKeyPhraseExtractionSkill();

// Create the skillset
Console.WriteLine("Creating or updating the skillset...");
List<SearchIndexerSkill> skills = new List<SearchIndexerSkill>();
skills.Add(ocrSkill);
skills.Add(mergeSkill);
skills.Add(languageDetectionSkill);
skills.Add(splitSkill);
skills.Add(entityRecognitionSkill);
skills.Add(keyPhraseExtractionSkill);

SearchIndexerSkillset skillset = CreateOrUpdateDemoSkillSet(indexerClient, skills, cognitiveServicesKey);

Krok 3: Vytvoření indexu

V tomto oddílu definujete schéma indexu, a to tak, že zadáte, která pole se mají zahrnout do prohledávatelného indexu, a pro jednotlivá pole poskytnete atributy vyhledávání. Pole mají typ a můžou přijímat argumenty, které určují, jak se pole používá (prohledávatelné, seřaditelné apod.). K vyhledání přesné shody s názvy polí ve zdroji není nutné, aby index tyto názvy polí obsahoval. V pozdějším kroku přidáte v indexeru mapování polí, pomocí kterých propojíte zdrojová a cílová pole. Pro tento krok definujte index pomocí konvencí pojmenování relevantních pro vaši vyhledávací aplikaci.

V tomto cvičení použijeme následující pole a jejich typy:

Názvy polí Typy polí
id Edm.String
content Edm.String
languageCode Edm.String
keyPhrases List<Edm.String>
organizations List<Edm.String>

Create DemoIndex – třída

Pole pro tento index jsou definována pomocí třídy modelu. Každá vlastnost třídy modelu má atributy, které určují chování odpovídajícího pole indexu při vyhledávání.

Třídu modelu přidáme do nového souboru C#. Klikněte pravým tlačítkem na projekt a vyberte Přidat>novou položku..., vyberte "Třída" a pojmenujte soubor DemoIndex.csa pak vyberte Přidat.

Ujistěte se, že chcete používat typy z Azure.Search.Documents.Indexes oborů názvů a System.Text.Json.Serialization oborů názvů.

Přidejte následující definici třídy modelu a přidejte ji do DemoIndex.cs stejného oboru názvů, do kterého vytvoříte index.

using Azure.Search.Documents.Indexes;
using System.Text.Json.Serialization;

namespace EnrichwithAI
{
    // The SerializePropertyNamesAsCamelCase is currently unsupported as of this writing. 
    // Replace it with JsonPropertyName
    public class DemoIndex
    {
        [SearchableField(IsSortable = true, IsKey = true)]
        [JsonPropertyName("id")]
        public string Id { get; set; }

        [SearchableField]
        [JsonPropertyName("content")]
        public string Content { get; set; }

        [SearchableField]
        [JsonPropertyName("languageCode")]
        public string LanguageCode { get; set; }

        [SearchableField]
        [JsonPropertyName("keyPhrases")]
        public string[] KeyPhrases { get; set; }

        [SearchableField]
        [JsonPropertyName("organizations")]
        public string[] Organizations { get; set; }
    }
}

Teď, když jste definovali třídu modelu, můžete vytvořit Program.cs definici indexu poměrně snadno. Název tohoto indexu bude demoindex. Pokud už index s tímto názvem existuje, odstraní se.

private static SearchIndex CreateDemoIndex(SearchIndexClient indexClient)
{
    FieldBuilder builder = new FieldBuilder();
    var index = new SearchIndex("demoindex")
    {
        Fields = builder.Build(typeof(DemoIndex))
    };

    try
    {
        indexClient.GetIndex(index.Name);
        indexClient.DeleteIndex(index.Name);
    }
    catch (RequestFailedException ex) when (ex.Status == 404)
    {
        //if the specified index not exist, 404 will be thrown.
    }

    try
    {
        indexClient.CreateIndex(index);
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine("Failed to create the index\n Exception message: {0}\n", ex.Message);
        ExitProgram("Cannot continue without an index");
    }

    return index;
}

Během testování můžete zjistit, že se pokoušíte vytvořit index vícekrát. Z tohoto důvodu zkontrolujte, jestli index, který chcete vytvořit, již existuje, než se ho pokusíte vytvořit.

Přidejte následující řádky do Main.

// Create the index
Console.WriteLine("Creating the index...");
SearchIndex demoIndex = CreateDemoIndex(indexClient);

Přidejte následující příkaz using k vyřešení nejednoznačného odkazu.

using Index = Azure.Search.Documents.Indexes.Models;

Další informace o konceptech indexů najdete v tématu Vytvoření indexu (REST API).

Krok 4: Vytvoření a spuštění indexeru

Do této chvíle jste vytvořili zdroj dat, sadu dovedností a index. Tyto tři komponenty se stanou součástí indexeru, který jednotlivé části sestaví do jediné operace s více fázemi. Pokud je chcete sloučit do indexeru, musíte nadefinovat mapování polí.

  • Mapování polí před sadou dovedností, mapování zdrojových polí ze zdroje dat na cílová pole v indexu. Pokud jsou názvy a typy polí na obou koncích stejné, nevyžaduje se žádné mapování.

  • Výstupní objektyFieldMapping se zpracovávají po sadě dovedností, odkazující na zdrojové názvy polí, které neexistují, dokud je dokument nerozlomí nebo obohacuje. TargetFieldName je pole v indexu.

Kromě připojení vstupů k výstupům můžete také použít mapování polí pro zploštělé datové struktury. Další informace naleznete v tématu Jak mapovat rozšířená pole na prohledávatelný index.

private static SearchIndexer CreateDemoIndexer(SearchIndexerClient indexerClient, SearchIndexerDataSourceConnection dataSource, SearchIndexerSkillset skillSet, SearchIndex index)
{
    IndexingParameters indexingParameters = new IndexingParameters()
    {
        MaxFailedItems = -1,
        MaxFailedItemsPerBatch = -1,
    };
    indexingParameters.Configuration.Add("dataToExtract", "contentAndMetadata");
    indexingParameters.Configuration.Add("imageAction", "generateNormalizedImages");

    SearchIndexer indexer = new SearchIndexer("demoindexer", dataSource.Name, index.Name)
    {
        Description = "Demo Indexer",
        SkillsetName = skillSet.Name,
        Parameters = indexingParameters
    };

    FieldMappingFunction mappingFunction = new FieldMappingFunction("base64Encode");
    mappingFunction.Parameters.Add("useHttpServerUtilityUrlTokenEncode", true);

    indexer.FieldMappings.Add(new FieldMapping("metadata_storage_path")
    {
        TargetFieldName = "id",
        MappingFunction = mappingFunction

    });
    indexer.FieldMappings.Add(new FieldMapping("content")
    {
        TargetFieldName = "content"
    });

    indexer.OutputFieldMappings.Add(new FieldMapping("/document/pages/*/organizations/*")
    {
        TargetFieldName = "organizations"
    });
    indexer.OutputFieldMappings.Add(new FieldMapping("/document/pages/*/keyPhrases/*")
    {
        TargetFieldName = "keyPhrases"
    });
    indexer.OutputFieldMappings.Add(new FieldMapping("/document/languageCode")
    {
        TargetFieldName = "languageCode"
    });

    try
    {
        indexerClient.GetIndexer(indexer.Name);
        indexerClient.DeleteIndexer(indexer.Name);
    }
    catch (RequestFailedException ex) when (ex.Status == 404)
    {
        //if the specified indexer not exist, 404 will be thrown.
    }

    try
    {
        indexerClient.CreateIndexer(indexer);
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine("Failed to create the indexer\n Exception message: {0}\n", ex.Message);
        ExitProgram("Cannot continue without creating an indexer");
    }

    return indexer;
}

Přidejte následující řádky do Main.

// Create the indexer, map fields, and execute transformations
Console.WriteLine("Creating the indexer and executing the pipeline...");
SearchIndexer demoIndexer = CreateDemoIndexer(indexerClient, dataSource, skillset, demoIndex);

Očekáváme, že dokončení zpracování indexeru nějakou dobu trvá. I když je sada dat malá, analytické dovednosti jsou výpočetně náročné. Některé dovednosti, třeba analýza obrazu, trvají dlouho.

Tip

Vytvoření indexeru vyvolá kanál. Pokud dojde k nějakému problému při komunikaci s daty, při mapování vstupů a výstupů nebo s pořadím operací, zobrazí se v této fázi.

Prozkoumání vytváření indexeru

Kód se nastaví "maxFailedItems" na -1, který dává modulu indexování pokyn ignorovat chyby během importu dat. To je užitečné, protože v ukázkovém zdroji dat je velmi málo dokumentů. Pro větší zdroje dat by tato hodnota byla větší než 0.

Všimněte si také, že "dataToExtract" je nastavena na "contentAndMetadata"hodnotu . Tento příkaz dává indexeru pokyn, aby automaticky extrahoval obsah z různých formátů souborů, stejně jako metadata, která s jednotlivými soubory souvisí.

Když se extrahuje obsah, můžete nastavit imageAction, aby se z obrázků nalezených ve zdroji dat extrahoval text. Sada "imageAction" na "generateNormalizedImages" konfiguraci v kombinaci s dovednostmi OCR Skill and Text Merge Skill říká indexeru, aby extrahoval text z obrázků (například slovo "stop" z znaménka zastavení provozu) a vložil ho jako součást pole obsahu. Toto chování platí jak pro obrázky vložené do dokumentů (třeba obrázek v souboru PDF), tak pro obrázky nalezené ve zdroji dat, např. soubor JPG.

4. Monitorování indexování

Až se indexer nadefinuje, automaticky se spustí, až se odešle požadavek. Podle kognitivních dovedností, které jste definovali, může indexování trvat déle, než jste čekali. Pokud chcete zjistit, jestli je indexer stále spuštěný, použijte metodu GetStatus .

private static void CheckIndexerOverallStatus(SearchIndexerClient indexerClient, SearchIndexer indexer)
{
    try
    {
        var demoIndexerExecutionInfo = indexerClient.GetIndexerStatus(indexer.Name);

        switch (demoIndexerExecutionInfo.Value.Status)
        {
            case IndexerStatus.Error:
                ExitProgram("Indexer has error status. Check the Azure Portal to further understand the error.");
                break;
            case IndexerStatus.Running:
                Console.WriteLine("Indexer is running");
                break;
            case IndexerStatus.Unknown:
                Console.WriteLine("Indexer status is unknown");
                break;
            default:
                Console.WriteLine("No indexer information");
                break;
        }
    }
    catch (RequestFailedException ex)
    {
        Console.WriteLine("Failed to get indexer overall status\n Exception message: {0}\n", ex.Message);
    }
}

demoIndexerExecutionInfo představuje aktuální stav a historii provádění indexeru.

Pro určité kombinace zdrojových souborů a dovedností jsou upozornění běžná a ne vždy představují problém. V tomto kurzu jsou upozornění neškodná (např. v souboru JPEG nejsou žádné textové vstupy).

Přidejte následující řádky do Main.

// Check indexer overall status
Console.WriteLine("Check the indexer overall status...");
CheckIndexerOverallStatus(indexerClient, demoIndexer);

V konzolových aplikacích azure Cognitive Search obvykle přidáme 2sekundové zpoždění před spuštěním dotazů, které vrací výsledky, ale protože dokončení rozšiřování trvá několik minut, zavřeme konzolovou aplikaci a místo toho použijeme jiný přístup.

Nejjednodušší možností je Průzkumník služby Search na portálu. Nejprve můžete spustit prázdný dotaz, který vrátí všechny dokumenty, nebo cílenější vyhledávání, které vrací nový obsah pole vytvořený kanálem.

  1. Na webu Azure Portal na stránce Přehled vyhledávání vyberte Indexy.

  2. Najděte demoindex v seznamu. Mělo by mít 14 dokumentů. Pokud je počet dokumentů nulový, indexer je stále spuštěný nebo se stránka ještě neaktualizovala.

  3. Vyberte demoindex. Průzkumník služby Search je první karta.

  4. Obsah je možné prohledávat hned po načtení prvního dokumentu. Pokud chcete ověřit, jestli obsah existuje, spusťte nespecifikovaný dotaz kliknutím na Hledat. Tento dotaz vrátí všechny aktuálně indexované dokumenty a poskytne vám představu o tom, co index obsahuje.

  5. V dalším kroku vložte následující řetězec, abyste lépe zvládli výsledky: search=*&$select=id, languageCode, organizations

Resetování a opětovné spuštění

V počátečních experimentálních fázích vývoje je nejproktičtějším přístupem k iteraci návrhu odstranit objekty ze služby Azure Cognitive Search a umožnit kódu je znovu sestavit. Názvy prostředků jsou jedinečné. Když se objekt odstraní, je možné ho znovu vytvořit se stejným názvem.

Vzorový kód pro tento kurz zkontroluje existující objekty a odstraní je, abyste mohli kód znovu spustit. Pomocí portálu můžete také odstranit indexy, indexery, zdroje dat a sady dovedností.

Shrnutí

Tento kurz ukázal základní kroky pro vytvoření rozšířeného kanálu indexování prostřednictvím vytváření součástí součástí: zdroje dat, sady dovedností, indexu a indexeru.

Předdefinované dovednosti byly zavedeny spolu s definicí sady dovedností a mechanikou řetězení dovedností prostřednictvím vstupů a výstupů. Také jste se dozvěděli, že outputFieldMappings v definici indexeru je nutné směrovat rozšířené hodnoty z kanálu do prohledávatelného indexu ve službě Azure Cognitive Search.

Nakonec jste se dozvěděli, jak testovat výsledky a resetovat systém pro další iterace. Zjistili jste, že zasílání dotazů na index vrací výstup vytvořený kanálem rozšířeného indexování. K tomu všemu jste se naučili, jak zkontrolovat stav indexeru a které objekty se mají před opětovným spuštěním kanálu odstranit.

Vyčištění prostředků

Když pracujete ve vlastním předplatném, je na konci projektu vhodné odebrat prostředky, které už nepotřebujete. Prostředky, které necháte běžet, vás stojí peníze. Můžete odstraňovat prostředky jednotlivě nebo odstraněním skupiny prostředků odstranit celou sadu prostředků najednou.

Prostředky můžete najít a spravovat na portálu pomocí odkazu Všechny prostředky nebo skupiny prostředků v levém navigačním podokně.

Další kroky

Teď, když znáte všechny objekty v kanálu rozšiřování AI, se podrobněji podíváme na definice sad dovedností a jednotlivé dovednosti.