Kurz: Vytvoření první vyhledávací aplikace v Azure Cognitive Search pomocí sady .NET SDK

V tomto kurzu se dozvíte, jak vytvořit webovou aplikaci, která dotazuje a vrací výsledky z indexu vyhledávání pomocí Azure Cognitive Search a sady Visual Studio.

V tomto kurzu se naučíte:

  • Nastavení vývojového prostředí
  • Modelování datových struktur
  • Vytvoření webové stránky pro shromažďování vstupů dotazů a zobrazení výsledků
  • Definování metody vyhledávání
  • Otestování aplikace

Dozvíte se také, jak přímočarý je vyhledávací hovor. Klíčové příkazy v kódu jsou zapouzdřeny v následujících několika řádcích:

var options = new SearchOptions()
{
    // The Select option specifies fields for the result set
    options.Select.Add("HotelName");
    options.Select.Add("Description");
};

var searchResult = await _searchClient.SearchAsync<Hotel>(model.searchText, options).ConfigureAwait(false);
model.resultList = searchResult.Value.GetResults().ToList();

Jedno volání se dotazuje na index vyhledávání a vrátí výsledky.

Hledání *fondu*

Přehled

V tomto kurzu se používá hotels-sample-index, který můžete rychle vytvořit ve vlastní vyhledávací službě krokováním v rychlém startu Import dat. Index obsahuje fiktivní hotelová data, která jsou k dispozici jako integrovaný zdroj dat v každé vyhledávací službě.

První lekce v tomto kurzu vytvoří základní strukturu dotazů a vyhledávací stránku, kterou v dalších lekcích vylepšíte tak, aby zahrnovala stránkování, omezující vlastnosti a prostředí s předsunutím.

Dokončenou verzi kódu najdete v následujícím projektu:

Požadavky

Instalace a spuštění projektu z GitHubu

Pokud chcete přejít na funkční aplikaci, stáhněte a spusťte hotový kód podle následujících kroků.

  1. Najděte ukázku na GitHubu: Vytvoření první aplikace.

  2. V kořenové složce vyberte Kód a pak vyberte Clone or Download ZIP ( Klonovat nebo Stáhnout ZIP ) a vytvořte tak svou soukromou místní kopii projektu.

  3. V sadě Visual Studio přejděte na a otevřete řešení pro základní vyhledávací stránku ("1-basic-search-page") a vyberte Spustit bez ladění (nebo stiskněte klávesu F5) a sestavte a spusťte program.

  4. Toto je index hotelů, takže zadejte některá slova, která můžete použít k hledání hotelů (například "wifi", "view", "bar", "parking"). Podívejte se na výsledky.

    Hledání *wifi*

Tato aplikace obsahuje základní komponenty pro sofistikovanější vyhledávání. Pokud s vývojem vyhledávání začínáte, můžete tuto aplikaci vytvořit krok za krokem a seznámit se s pracovním postupem. Následující části vám ukážou, jak na to.

Nastavení vývojového prostředí

Pokud chcete vytvořit tento projekt od začátku a posílit tak koncepty Azure Cognitive Search, začněte projektem sady Visual Studio.

  1. V sadě Visual Studio vyberte Nový>projekt a pak ASP.NET Core Web App (Model-View-Controller).

    Vytvoření cloudového projektu

  2. Pojmenujte projekt například FirstSearchApp a nastavte umístění. Vyberte Další.

  3. Přijměte výchozí hodnoty pro cílovou architekturu, typ ověřování a HTTPS. Vyberte Vytvořit.

  4. Nainstalujte klientskou knihovnu. V nástrojích> Správce >balíčků NuGetSpravovat balíčky NuGet pro řešení... vyberte Procházet a vyhledejte azure.search.documents. Nainstalujte Azure.Search.Documents (verze 11 nebo novější) a přijměte licenční smlouvy a závislosti.

    Přidání knihoven Azure pomocí NuGetu

V tomto kroku nastavte koncový bod a přístupový klíč pro připojení k vyhledávací službě, která poskytuje ukázkový index hotelů.

  1. Otevřete soubor appsettings.json a nahraďte výchozí řádky adresou URL vyhledávací služby (ve formátu https://<service-name>.search.windows.net) a klíčem rozhraní API pro správu nebo dotazování vaší vyhledávací služby. Vzhledem k tomu, že index nemusíte vytvářet ani aktualizovat, můžete pro tento kurz použít klíč dotazu.

    {
        "SearchServiceUri": "<YOUR-SEARCH-SERVICE-URI>",
        "SearchServiceQueryApiKey": "<YOUR-SEARCH-SERVICE-API-KEY>"
    }
    
  2. V Průzkumník řešení vyberte soubor a ve vlastnostech změňte nastavení Kopírovat do výstupního adresáře na Kopírovat, pokud je novější.

    Kopírování nastavení aplikace do výstupu

Modelování datových struktur

Modely (třídy C#) slouží ke komunikaci dat mezi klientem (zobrazení), serverem (kontrolerem) a také cloudem Azure pomocí architektury MVC (model, zobrazení, kontroler). Tyto modely obvykle odrážejí strukturu dat, ke kterým se přistupuje.

V tomto kroku budete modelovat datové struktury vyhledávacího indexu a také hledaný řetězec používaný při komunikaci zobrazení a kontroleru. V indexu hotelů má každý hotel mnoho pokojů a každý hotel má vícedílnou adresu. Kompletní reprezentace hotelu je hierarchická vnořená datová struktura. K vytvoření každé komponenty budete potřebovat tři třídy.

Sada tříd Hotel, Address a Room jsou známé jako komplexní typy, která je důležitou součástí Azure Cognitive Search. Komplexní typy mohou mít mnoho úrovní hloubky tříd a podtříd a umožňují reprezentaci mnohem složitějších datových struktur než použití jednoduchých typů (třída obsahující pouze primitivní členy).

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

  2. Vyberte Třída a pojmenujte položku Hotel.cs. Veškerý obsah souboru Hotel.cs nahraďte následujícím kódem. Všimněte si členů třídy Address (Adresa ) a Room (Místnost ), tato pole jsou samotné třídy, takže pro ně budete také potřebovat modely.

    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    using Microsoft.Spatial;
    using System;
    using System.Text.Json.Serialization;
    
    namespace FirstAzureSearchApp.Models
    {
        public partial class Hotel
        {
            [SimpleField(IsFilterable = true, IsKey = true)]
            public string HotelId { get; set; }
    
            [SearchableField(IsSortable = true)]
            public string HotelName { get; set; }
    
            [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnLucene)]
            public string Description { get; set; }
    
            [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)]
            [JsonPropertyName("Description_fr")]
            public string DescriptionFr { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string Category { get; set; }
    
            [SearchableField(IsFilterable = true, IsFacetable = true)]
            public string[] Tags { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public bool? ParkingIncluded { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public DateTimeOffset? LastRenovationDate { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public double? Rating { get; set; }
    
            public Address Address { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true)]
            public GeographyPoint Location { get; set; }
    
            public Room[] Rooms { get; set; }
        }
    }
    
  3. Opakujte stejný postup vytvoření modelu pro třídu Address , pojmenování souboru Address.cs. Nahraďte obsah následujícím kódem.

    using Azure.Search.Documents.Indexes;
    
    namespace FirstAzureSearchApp.Models
    {
        public partial class Address
        {
            [SearchableField]
            public string StreetAddress { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string City { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string StateProvince { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string PostalCode { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string Country { get; set; }
        }
    }
    
  4. A znovu postupujte podle stejného postupu a vytvořte třídu Room a pojměte soubor Room.cs.

    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    using System.Text.Json.Serialization;
    
    namespace FirstAzureSearchApp.Models
    {
        public partial class Room
        {
            [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnMicrosoft)]
            public string Description { get; set; }
    
            [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrMicrosoft)]
            [JsonPropertyName("Description_fr")]
            public string DescriptionFr { get; set; }
    
            [SearchableField(IsFilterable = true, IsFacetable = true)]
            public string Type { get; set; }
    
            [SimpleField(IsFilterable = true, IsFacetable = true)]
            public double? BaseRate { get; set; }
    
            [SearchableField(IsFilterable = true, IsFacetable = true)]
            public string BedOptions { get; set; }
    
            [SimpleField(IsFilterable = true, IsFacetable = true)]
            public int SleepsCount { get; set; }
    
            [SimpleField(IsFilterable = true, IsFacetable = true)]
            public bool? SmokingAllowed { get; set; }
    
            [SearchableField(IsFilterable = true, IsFacetable = true)]
            public string[] Tags { get; set; }
        }
    }
    
  5. Poslední model, který vytvoříte v tomto kurzu, je třída s názvem SearchData , která představuje vstup uživatele (searchText) a výstup hledání (resultList). Typ výstupu je kritický, SearchResults<Hotel>, protože tento typ přesně odpovídá výsledkům hledání, a tento odkaz musíte předat zobrazení. Nahraďte výchozí šablonu následujícím kódem.

    using Azure.Search.Documents.Models;
    
    namespace FirstAzureSearchApp.Models
    {
        public class SearchData
        {
            // The text to search for.
            public string searchText { get; set; }
    
            // The list of results.
            public SearchResults<Hotel> resultList;
        }
    }
    

Vytvoření webové stránky

Šablony projektů se dodávají s několika klientskými zobrazeními umístěnými ve složce Zobrazení . Přesná zobrazení závisí na verzi Core .NET, kterou používáte (v této ukázce se používá verze 3.1). Pro účely tohoto kurzu upravíte soubor Index.cshtml tak, aby zahrnoval prvky vyhledávací stránky.

Odstraňte obsah souboru Index.cshtml v celém jeho rozsahu a znovu ho vytvořte v následujících krocích.

  1. Kurz používá v zobrazení dva malé obrázky: logo Azure a ikonu lupy vyhledávání (azure-logo.png a search.png). Zkopírujte obrázky z projektu GitHub do složky wwwroot/images ve vašem projektu.

  2. První řádek souboru Index.cshtml by měl odkazovat na model používaný ke komunikaci dat mezi klientem (zobrazením) a serverem (kontrolerem), což je model SearchData vytvořený dříve. Přidejte tento řádek do souboru Index.cshtml.

    @model FirstAzureSearchApp.Models.SearchData
    
  3. Standardním postupem je zadat název zobrazení, takže další řádky by měly být:

    @{
        ViewData["Title"] = "Home Page";
    }
    
  4. Za nadpisem zadejte odkaz na šablonu stylů HTML, kterou brzy vytvoříte.

    <head>
        <link rel="stylesheet" href="~/css/hotels.css" />
    </head>
    
  5. Tělo zobrazení zpracovává dva případy použití. Nejprve musí při prvním použití poskytnout prázdnou stránku, aby se zadal jakýkoli hledaný text. Za druhé musí kromě vyhledávacího textového pole zpracovávat i výsledky opakovaných dotazů.

    Pokud chcete zpracovat oba případy, musíte zkontrolovat, jestli má model zadaný do zobrazení hodnotu null. Model s hodnotou null označuje první případ použití (počáteční spuštění aplikace). Do souboru Index.cshtml přidejte následující kód a přečtěte si komentáře.

    <body>
    <h1 class="sampleTitle">
        <img src="~/images/azure-logo.png" width="80" />
        Hotels Search
    </h1>
    
    @using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        // Display the search text box, with the search icon to the right of it.
        <div class="searchBoxForm">
            @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox" }) <input class="searchBoxSubmit" type="submit" value="">
        </div>
    
        @if (Model != null)
        {
            // Show the result count.
            <p class="sampleText">
                @Model.resultList.TotalCount Results
            </p>
    
            var results = Model.resultList.GetResults().ToList();
    
            @for (var i = 0; i < results.Count; i++)
            {
                // Display the hotel name and description.
                @Html.TextAreaFor(m => results[i].Document.HotelName, new { @class = "box1" })
                @Html.TextArea($"desc{i}", results[i].Document.Description, new { @class = "box2" })
            }
        }
    }
    </body>
    
  6. Přidejte šablonu stylů. V sadě Visual Studio v části Soubor>nový>soubor vyberte Šablona stylů (se zvýrazněnou možností Obecné ).

    Nahraďte výchozí kód následujícím kódem. Do tohoto souboru nebudeme zacházet podrobněji, styly jsou standardní HTML.

    textarea.box1 {
        width: 648px;
        height: 30px;
        border: none;
        background-color: azure;
        font-size: 14pt;
        color: blue;
        padding-left: 5px;
    }
    
    textarea.box2 {
        width: 648px;
        height: 100px;
        border: none;
        background-color: azure;
        font-size: 12pt;
        padding-left: 5px;
        margin-bottom: 24px;
    }
    
    .sampleTitle {
        font: 32px/normal 'Segoe UI Light',Arial,Helvetica,Sans-Serif;
        margin: 20px 0;
        font-size: 32px;
        text-align: left;
    }
    
    .sampleText {
        font: 16px/bold 'Segoe UI Light',Arial,Helvetica,Sans-Serif;
        margin: 20px 0;
        font-size: 14px;
        text-align: left;
        height: 30px;
    }
    
    .searchBoxForm {
        width: 648px;
        box-shadow: 0 0 0 1px rgba(0,0,0,.1), 0 2px 4px 0 rgba(0,0,0,.16);
        background-color: #fff;
        display: inline-block;
        border-collapse: collapse;
        border-spacing: 0;
        list-style: none;
        color: #666;
    }
    
    .searchBox {
        width: 568px;
        font-size: 16px;
        margin: 5px 0 1px 20px;
        padding: 0 10px 0 0;
        border: 0;
        max-height: 30px;
        outline: none;
        box-sizing: content-box;
        height: 35px;
        vertical-align: top;
    }
    
    .searchBoxSubmit {
        background-color: #fff;
        border-color: #fff;
        background-image: url(/images/search.png);
        background-repeat: no-repeat;
        height: 20px;
        width: 20px;
        text-indent: -99em;
        border-width: 0;
        border-style: solid;
        margin: 10px;
        outline: 0;
    }
    
  7. Uložte soubor šablon stylů jako hotels.css do složky wwwroot/css spolu s výchozím souborem site.css.

Tím se náš pohled dokončí. V tomto okamžiku se modely i zobrazení dokončí. Zbývá jen ovladač, který všechno spojí dohromady.

Definování metod

V tomto kroku upravte obsah domovského ovladače.

  1. Otevřete soubor HomeController.cs a nahraďte příkazy using následujícími příkazy.

    using Azure;
    using Azure.Search.Documents;
    using Azure.Search.Documents.Indexes;
    using FirstAzureSearchApp.Models;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using System;
    using System.Diagnostics;
    using System.Linq;
    using System.Threading.Tasks;
    

Přidání metod indexu

V aplikaci MVC je metoda Index() výchozí metodou akce pro libovolný kontroler. Otevře stránku HTML indexu. Výchozí metoda, která nebere žádné parametry, se používá v tomto kurzu pro případ použití spuštění aplikace: vykreslení prázdné vyhledávací stránky.

V této části rozšiřujeme metodu tak, aby podporovala druhý případ použití: vykreslení stránky, když uživatel zadal hledaný text. Pro podporu tohoto případu je metoda indexu rozšířena tak, aby jako parametr převzala model.

  1. Přidejte následující metodu za výchozí metodu Index().

        [HttpPost]
        public async Task<ActionResult> Index(SearchData model)
        {
            try
            {
                // Ensure the search string is valid.
                if (model.searchText == null)
                {
                    model.searchText = "";
                }
    
                // Make the Azure Cognitive Search call.
                await RunQueryAsync(model);
            }
    
            catch
            {
                return View("Error", new ErrorViewModel { RequestId = "1" });
            }
            return View(model);
        }
    

    Všimněte si asynchronní deklarace metody a volání awaitrunQueryAsync. Tato klíčová slova se starají o asynchronní volání, a tak se vyhýbají blokování vláken na serveru.

    Blok catch používá výchozí model chyb, který byl vytvořen.

Poznamenejte si zpracování chyb a další výchozí zobrazení a metody.

V závislosti na verzi .NET Core, kterou používáte, se vytvoří mírně odlišná sada výchozích zobrazení. Pro .NET Core 3.1 jsou výchozí zobrazení Index, Ochrana osobních údajů a Chyba. Tyto výchozí stránky můžete zobrazit při spuštění aplikace a zjistit, jak se s nimi pracuje v kontroleru.

Zobrazení chyb budete testovat později v tomto kurzu.

V ukázce GitHubu se odstraní nepoužívané zobrazení a související akce.

Přidání metody RunQueryAsync

Volání Azure Cognitive Search je zapouzdřené v naší metodě RunQueryAsync.

  1. Nejprve přidejte několik statických proměnných pro nastavení služby Azure a volání, které je zahájí.

        private static SearchClient _searchClient;
        private static SearchIndexClient _indexClient;
        private static IConfigurationBuilder _builder;
        private static IConfigurationRoot _configuration;
    
        private void InitSearch()
        {
            // Create a configuration using appsettings.json
            _builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
            _configuration = _builder.Build();
    
            // Read the values from appsettings.json
            string searchServiceUri = _configuration["SearchServiceUri"];
            string queryApiKey = _configuration["SearchServiceQueryApiKey"];
    
            // Create a service and index client.
            _indexClient = new SearchIndexClient(new Uri(searchServiceUri), new AzureKeyCredential(queryApiKey));
            _searchClient = _indexClient.GetSearchClient("hotels");
        }
    
  2. Teď přidejte samotnou metodu RunQueryAsync .

    private async Task<ActionResult> RunQueryAsync(SearchData model)
    {
        InitSearch();
    
        var options = new SearchOptions() 
        { 
            IncludeTotalCount = true
        };
    
        // Enter Hotel property names into this list so only these values will be returned.
        // If Select is empty, all values will be returned, which can be inefficient.
        options.Select.Add("HotelName");
        options.Select.Add("Description");
    
        // For efficiency, the search call should be asynchronous, so use SearchAsync rather than Search.
        model.resultList = await _searchClient.SearchAsync<Hotel>(model.searchText, options).ConfigureAwait(false);          
    
        // Display the results.
        return View("Index", model);
    }
    

    V této metodě se nejprve ujistěte, že je inicializována naše konfigurace Azure, a pak nastavte některé možnosti hledání. Možnost Vybrat určuje, která pole se mají vrátit ve výsledcích, a odpovídají tak názvům vlastností ve třídě hotelu . Pokud funkci Select vynecháte, vrátí se všechna neskrytá pole, což může být neefektivní, pokud vás zajímá jenom podmnožina všech možných polí.

    Asynchronní volání hledání formuluje požadavek (modelovaný jako searchText) a odpověď (modelovaný jako searchResult). Pokud tento kód ladíte, je třída SearchResult vhodným kandidátem pro nastavení bodu zarážky, pokud potřebujete prozkoumat obsah souboru model.resultList. Měli byste zjistit, že je intuitivní, poskytuje jenom data, která jste požadovali, a nic jiného.

Otestování aplikace

Teď zkontrolujeme, jestli aplikace funguje správně.

  1. Vyberte Spustit ladění>bez ladění nebo stiskněte klávesu F5. Pokud aplikace běží podle očekávání, měli byste získat počáteční zobrazení Index.

    Otevření aplikace

  2. Zadejte řetězec dotazu, například "pláž" (nebo libovolný text, který vám přijde na mysl) a kliknutím na ikonu hledání odešlete žádost.

    Hledání *beach*

  3. Zkuste zadat "pět hvězdiček". Všimněte si, že tento dotaz nevrací žádné výsledky. Sofistikovanější vyhledávání by zacházeli s "pěti hvězdičkou" jako se synonymem pro "luxus" a vrátili by tyto výsledky. Podpora synonym je k dispozici v Azure Cognitive Search, ale v této sérii kurzů se o tom nezabývá.

  4. Zkuste jako hledaný text zadat "hot". Nevrací položky se slovem "hotel". Naše hledání vyhledává jenom celá slova, i když se vrátí několik výsledků.

  5. Zkuste další slova: "pool", "sunshine", "view" a cokoliv. Uvidíte, že Azure Cognitive Search funguje na své nejjednodušší, ale přesto přesvědčivé úrovni.

Testovací podmínky a chyby hraničních zařízení

Je důležité ověřit, že naše funkce zpracování chyb fungují tak, jak mají, i když všechno funguje perfektně.

  1. V metodě Index za volání try { zadejte řádek Throw new Exception(). Tato výjimka vynutí chybu při hledání textu.

  2. Spusťte aplikaci, jako hledaný text zadejte "bar" a klikněte na ikonu hledání. Výsledkem výjimky by mělo být zobrazení chyb.

    Vynucení chyby

    Důležité

    Vrácení čísel vnitřních chyb na chybových stránkách se považuje za bezpečnostní riziko. Pokud je vaše aplikace určená pro obecné použití, postupujte podle osvědčených postupů zabezpečení a zjistěte, co vrátit, když dojde k chybě.

  3. Pokud jste spokojení, že zpracování chyb funguje tak, jak má, odeberte vyvolání nové výjimky().

Shrnutí

Vezměte v úvahu následující poznatky z tohoto projektu:

  • Volání Azure Cognitive Search je stručné a výsledky se snadno interpretují.
  • Asynchronní volání přidávají kontroleru malou složitost, ale jsou osvědčeným postupem, který zvyšuje výkon.
  • Tato aplikace provedla přímočaré vyhledávání textu definované tím, co je nastavené v searchOptions. Tato jedna třída však může být naplněna mnoha členy, které přidávají sofistikovanost hledání. S trochou práce můžete tuto aplikaci výrazně zvýraznit.

Další kroky

Pokud chcete zlepšit uživatelské prostředí, přidejte další funkce, zejména stránkování (buď pomocí čísel stránek, nebo nekonečné posouvání), a automatické dokončování/návrhy. Můžete také zvážit další možnosti hledání (například geografické vyhledávání hotelů v zadaném okruhu od daného bodu) a řazení výsledků hledání.

Tyto další kroky jsou popsané ve zbývajících kurzech. Začněme stránkováním.