Jak používat Azure.Search.Documents v aplikaci .NET v jazyce C#

Tento článek vysvětluje, jak vytvářet a spravovat vyhledávací objekty pomocí jazyka C# a klientské knihovny Azure.Search.Documents (verze 11) v sadě Azure SDK pro .NET.

O verzi 11

Sada Azure SDK pro .NET obsahuje klientskou knihovnu Azure.Search.Documents od týmu sady Azure SDK, která je funkčně ekvivalentní předchozí klientské knihovně Microsoft.Azure.Search. Verze 11 je konzistentnější z hlediska programovatelnosti Azure. Mezi příklady patří AzureKeyCredential ověřování klíčů a serializace System.Text.Json.Serialization pro serializaci JSON.

Stejně jako u předchozích verzí můžete tuto knihovnu použít k:

  • Vytváření a správa vyhledávacích indexů, zdrojů dat, indexerů, sad dovedností a map synonym
  • Načtení a správa vyhledávacích dokumentů v indexu
  • Provádění dotazů, a to vše bez nutnosti zabývat se podrobnostmi HTTP a JSON
  • Vyvolání a správa rozšiřování AI (sady dovedností) a výstupů

Knihovna se distribuuje jako jeden balíček NuGet Azure.Search.Documents, který obsahuje všechna rozhraní API používaná pro programový přístup ke vyhledávací službě.

Klientská knihovna definuje třídy jako SearchIndex, a , a SearchDocumenttaké operace jako SearchIndexClient.CreateIndex a SearchClient.Search na třídách SearchClientSearchIndexClient. SearchField Tyto třídy jsou uspořádány do následujících oborů názvů:

Azure.Search.Documents (verze 11) cílí na specifikaci vyhledávací služby 2020-06-30.

Klientská knihovna neposkytuje operace správy služeb, jako je vytváření a škálování vyhledávacích služeb a správa klíčů rozhraní API. Pokud potřebujete spravovat vyhledávací prostředky z aplikace .NET, použijte knihovnu Microsoft.Azure.Management.Search v sadě Azure SDK pro .NET.

Upgrade na v11

Pokud jste používali předchozí verzi sady .NET SDK a chcete upgradovat na aktuální obecně dostupnou verzi, přečtěte si téma Upgrade na sadu .NET SDK služby Azure AI Search verze 11.

Požadavky sady SDK

  • Visual Studio 2019 nebo novější

  • Vlastní Search Azure AI. Abyste mohli používat sadu SDK, budete potřebovat název služby a jeden nebo více klíčů rozhraní API. Pokud ji nemáte, vytvořte na portálu službu.

  • Stáhněte balíček Azure.Search.Documents pomocí balíčků NuGet Tools>Správce balíčků> Manage NuGet pro řešení v sadě Visual Studio. Vyhledejte název Azure.Search.Documentsbalíčku .

Sada Azure SDK pro .NET odpovídá .NET Standard 2.0.

Příklad aplikace

Tento článek se "učí podle příkladu" a spoléhá na příklad kódu DotNetHowTo na GitHubu, aby ilustroval základní koncepty ve službě Azure AI Search – konkrétně jak vytvořit, načíst a dotazovat index vyhledávání.

Pro zbytek tohoto článku předpokládejme, že nový index s názvem "hotels", naplněný několika dokumenty, s několika dotazy, které odpovídají výsledkům.

Níže je hlavní program zobrazující celkový tok:

// This sample shows how to delete, create, upload documents and query an index
static void Main(string[] args)
{
    IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
    IConfigurationRoot configuration = builder.Build();

    SearchIndexClient indexClient = CreateSearchIndexClient(configuration);

    string indexName = configuration["SearchIndexName"];

    Console.WriteLine("{0}", "Deleting index...\n");
    DeleteIndexIfExists(indexName, indexClient);

    Console.WriteLine("{0}", "Creating index...\n");
    CreateIndex(indexName, indexClient);

    SearchClient searchClient = indexClient.GetSearchClient(indexName);

    Console.WriteLine("{0}", "Uploading documents...\n");
    UploadDocuments(searchClient);

    SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

    Console.WriteLine("{0}", "Run queries...\n");
    RunQueries(indexClientForQueries);

    Console.WriteLine("{0}", "Complete.  Press any key to end application...\n");
    Console.ReadKey();
}

Dále je částečný snímek obrazovky s výstupem za předpokladu, že spustíte tuto aplikaci s platným názvem služby a klíči rozhraní API:

Screenshot of the Console.WriteLine output from the sample program.

Typy klientů

Klientská knihovna používá pro různé operace tři typy klientů: SearchIndexClient k vytvoření, aktualizaci nebo odstranění indexů, SearchClient k načtení nebo dotazování indexu a SearchIndexerClient práci s indexery a sadami dovedností. Tento článek se zaměřuje na první dva.

Minimálně všichni klienti vyžadují název služby nebo koncový bod a klíč rozhraní API. Tyto informace je běžné zadat v konfiguračním souboru, podobně jako appsettings.json v souboru ukázkové aplikace DotNetHowTo. Pokud chcete číst z konfiguračního souboru, přidejte using Microsoft.Extensions.Configuration; ho do svého programu.

Následující příkaz vytvoří klienta indexu použitého k vytvoření, aktualizaci nebo odstranění indexů. Přebírá koncový bod služby a klíč rozhraní API pro správu.

private static SearchIndexClient CreateSearchIndexClient(IConfigurationRoot configuration)
{
    string searchServiceEndPoint = configuration["SearchServiceEndPoint"];
    string adminApiKey = configuration["SearchServiceAdminApiKey"];

    SearchIndexClient indexClient = new SearchIndexClient(new Uri(searchServiceEndPoint), new AzureKeyCredential(adminApiKey));
    return indexClient;
}

Další příkaz vytvoří vyhledávacího klienta sloužícího k načtení dokumentů nebo spouštění dotazů. SearchClient vyžaduje index. K načtení dokumentů budete potřebovat klíč rozhraní API pro správu, ale ke spouštění dotazů můžete použít klíč rozhraní API pro dotazy.

string indexName = configuration["SearchIndexName"];

private static SearchClient CreateSearchClientForQueries(string indexName, IConfigurationRoot configuration)
{
    string searchServiceEndPoint = configuration["SearchServiceEndPoint"];
    string queryApiKey = configuration["SearchServiceQueryApiKey"];

    SearchClient searchClient = new SearchClient(new Uri(searchServiceEndPoint), indexName, new AzureKeyCredential(queryApiKey));
    return searchClient;
}

Poznámka:

Pokud pro operaci importu zadáte neplatný klíč (například klíč dotazu, ve kterém byl požadován klíč správce), SearchClient vyvolá se CloudException chybová zpráva Zakázáno při prvním volání metody operace. Pokud k tomu dojde, pečlivě zkontrolujte klíč rozhraní API.

Odstranění indexu

V počátečních fázích vývoje můžete chtít zahrnout DeleteIndex příkaz, který odstraní probíhající index, abyste ho mohli znovu vytvořit s aktualizovanou definicí. Ukázkový kód pro Azure AI Search často obsahuje krok odstranění, abyste mohli ukázku spustit znovu.

Následující volání DeleteIndexIfExistsřádku:

Console.WriteLine("{0}", "Deleting index...\n");
DeleteIndexIfExists(indexName, indexClient);

Tato metoda pomocí dané SearchIndexClient metody zkontroluje, jestli index existuje, a pokud ano, odstraní ho:

private static void DeleteIndexIfExists(string indexName, SearchIndexClient indexClient)
{
    try
    {
        if (indexClient.GetIndex(indexName) != null)
        {
            indexClient.DeleteIndex(indexName);
        }
    }
    catch (RequestFailedException e) when (e.Status == 404)
    {
        // Throw an exception if the index name isn't found
        Console.WriteLine("The index doesn't exist. No deletion occurred.");

Poznámka:

Ukázkový kód v tomto článku používá synchronní metody pro jednoduchost, ale měli byste použít asynchronní metody ve vlastních aplikacích, aby byly škálovatelné a responzivní. Například ve výše uvedené metodě můžete místo DeleteIndexAsyncDeleteIndex.

Vytvoření indexu

K vytvoření indexu můžete použít SearchIndexClient .

Následující metoda vytvoří nový SearchIndex objekt se seznamem SearchField objektů, které definují schéma nového indexu. Každé pole má název, datový typ a několik atributů, které definují chování hledání.

Pole lze definovat z třídy modelu pomocí FieldBuilder. Třída FieldBuilder používá reflexi k vytvoření seznamu SearchField objektů pro index prozkoumáním veřejných vlastností a atributů dané Hotel třídy modelu. Později se podrobněji podíváme na Hotel třídu.

private static void CreateIndex(string indexName, SearchIndexClient indexClient)
{
    FieldBuilder fieldBuilder = new FieldBuilder();
    var searchFields = fieldBuilder.Build(typeof(Hotel));

    var definition = new SearchIndex(indexName, searchFields);

    indexClient.CreateOrUpdateIndex(definition);
}

Kromě polí můžete do indexu přidat také profily bodování, návrhy nebo možnosti CORS (tyto parametry jsou z ukázky vynechány kvůli stručnosti). Další informace o objektu SearchIndex a jejích součástech najdete v SearchIndex seznamu vlastností a také v referenčních informacích k rozhraní REST API.

Poznámka:

V případě potřeby můžete vždy vytvořit seznam Field objektů přímo místo použití FieldBuilder . Například možná nebudete chtít použít třídu modelu nebo budete muset použít existující třídu modelu, kterou nechcete upravovat přidáním atributů.

Volání CreateIndex v Main()

Main vytvoří nový index "hotels" zavoláním výše uvedené metody:

Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, indexClient);

Použití třídy modelu pro reprezentaci dat

Ukázka DotNetHowTo používá třídy modelů pro datové struktury Hotel, Address a Room . Hotel odkazy Address, komplexní typ jedné úrovně (pole s více částmi) a Room (kolekce vícedílných polí).

Pomocí těchto typů můžete vytvořit a načíst index a strukturovat odpověď z dotazu:

// Use-case: <Hotel> in a field definition
FieldBuilder fieldBuilder = new FieldBuilder();
var searchFields = fieldBuilder.Build(typeof(Hotel));

// Use-case: <Hotel> in a response
private static void WriteDocuments(SearchResults<Hotel> searchResults)
{
    foreach (SearchResult<Hotel> result in searchResults.GetResults())
    {
        Console.WriteLine(result.Document);
    }

    Console.WriteLine();
}

Alternativním přístupem je přímé přidání polí do indexu. Následující příklad ukazuje jen několik polí.

 SearchIndex index = new SearchIndex(indexName)
 {
     Fields =
         {
             new SimpleField("hotelId", SearchFieldDataType.String) { IsKey = true, IsFilterable = true, IsSortable = true },
             new SearchableField("hotelName") { IsFilterable = true, IsSortable = true },
             new SearchableField("hotelCategory") { IsFilterable = true, IsSortable = true },
             new SimpleField("baseRate", SearchFieldDataType.Int32) { IsFilterable = true, IsSortable = true },
             new SimpleField("lastRenovationDate", SearchFieldDataType.DateTimeOffset) { IsFilterable = true, IsSortable = true }
         }
 };

Definice polí

Datový model v .NET a jeho odpovídající schéma indexu by mělo podporovat vyhledávací prostředí, které chcete dát koncovému uživateli. Každý objekt nejvyšší úrovně v .NET, například vyhledávací dokument v indexu vyhledávání, odpovídá výsledku hledání, který byste zobrazili ve svém uživatelském rozhraní. Například v aplikaci pro vyhledávání hotelů můžou koncoví uživatelé chtít hledat podle názvu hotelu, funkcí hotelu nebo vlastností konkrétní místnosti.

V rámci každé třídy je pole definováno s datovým typem a atributy, které určují, jak se používá. Název každé veřejné vlastnosti v každé třídě se mapuje na pole se stejným názvem v definici indexu.

Podívejte se na následující fragment kódu, který z třídy Hotel načítá několik definic polí. Všimněte si, že adresy a místnosti jsou typy jazyka C# s vlastními definicemi tříd (pokud je chcete zobrazit, podívejte se na vzorový kód). Oba typy jsou složité. Další informace naleznete v tématu Modelování složitých typů.

public partial class Hotel
{
    [SimpleField(IsKey = true, IsFilterable = 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(IsFilterable = true, IsSortable = true, IsFacetable = true)]
    public string Category { get; set; }

    [JsonIgnore]
    public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;

    [SearchableField]
    public Address Address { get; set; }

    public Room[] Rooms { get; set; }

Volba třídy pole

Při definování polí můžete použít základní SearchField třídu nebo můžete použít odvozené pomocné modely, které slouží jako "šablony", s předem nakonfigurovanými vlastnostmi.

Přesně jedno pole v indexu musí sloužit jako klíč dokumentu (IsKey = true). Musí to být řetězec a musí jednoznačně identifikovat každý dokument. Je také nutné mít IsHidden = true, což znamená, že ve výsledcích hledání není vidět.

Typ pole Popis a využití
SearchField Základní třída s většinou vlastností nastavených na hodnotu null s výjimkou Name toho, co je povinné, a AnalyzerName která výchozí hodnota je standardní Lucene.
SimpleField Pomocný model. Může to být libovolný datový typ, který je vždy nehledatelný (je ignorován pro dotazy fulltextového vyhledávání) a je načítaný (není skrytý). Ostatní atributy jsou ve výchozím nastavení vypnuté, ale je možné je povolit. Můžete použít SimpleField pro ID dokumentu nebo pole použitá pouze v filtrech, omezujících vlastností nebo v bodovacích profilech. Pokud ano, nezapomeňte použít všechny atributy, které jsou nezbytné pro daný scénář, například IsKey = true pro ID dokumentu. Další informace najdete v tématu SimpleFieldAttribute.cs ve zdrojovém kódu.
SearchableField Pomocný model. Musí to být řetězec, který je vždy prohledávatelný a načístelný. Ostatní atributy jsou ve výchozím nastavení vypnuté, ale je možné je povolit. Vzhledem k tomu, že tento typ pole je prohledávatelný, podporuje synonyma a úplný doplněk vlastností analyzátoru. Další informace najdete v SearchableFieldAttribute.cs ve zdrojovém kódu.

Bez ohledu na to, jestli používáte základní SearchField rozhraní API nebo jeden z pomocných modelů, musíte explicitně povolit atributy filtru, omezující vlastnosti a řazení. Například IsFilterable, IsSortable a IsFacetable musí být explicitně přiřazeny, jak je znázorněno v ukázce výše.

Přidání atributů pole

Všimněte si, jak je každé pole zdobeno atributy, jako IsFilterablejsou , IsSortable, IsKeya AnalyzerName. Tyto atributy se mapují přímo na odpovídající atributy pole v indexu služby Azure AI Search. Třída FieldBuilder používá tyto vlastnosti k vytvoření definic polí pro index.

Mapování typů polí

Typy .NET vlastností mapují na ekvivalentní typy polí v definici indexu. Například řetězcová vlastnost Category se mapuje na pole category, které je typu Edm.String. Existují podobná mapování typů mezi bool?, Edm.Boolean, DateTimeOffset?a Edm.DateTimeOffset tak dále.

Všimli jste si nemovitosti SmokingAllowed ?

[JsonIgnore]
public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;

Atribut JsonIgnore na této vlastnosti říká FieldBuilder , aby ho serializovat do indexu jako pole. To je skvělý způsob, jak vytvořit počítané vlastnosti na straně klienta, které můžete použít jako pomocné rutiny ve vaší aplikaci. V tomto případě vlastnost odráží, SmokingAllowed zda některý Room z kolekcí Rooms umožňuje kouření. Pokud jsou všechny nepravdivé, znamená to, že celý hotel neumožňuje kouření.

Načtení indexu

Dalším krokem, který Main naplní nově vytvořený index "hotels". Tento soubor indexu se provádí v následující metodě: (Kód nahrazený znakem "..." pro ilustraci. Podívejte se na úplné ukázkové řešení pro celý kód základního souboru dat.)

private static void UploadDocuments(SearchClient searchClient)
{
    IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create(
        IndexDocumentsAction.Upload(
            new Hotel()
            {
                HotelId = "1",
                HotelName = "Secret Point Motel",
                ...
                Address = new Address()
                {
                    StreetAddress = "677 5th Ave",
                    ...
                },
                Rooms = new Room[]
                {
                    new Room()
                    {
                        Description = "Budget Room, 1 Queen Bed (Cityside)",
                        ...
                    },
                    new Room()
                    {
                        Description = "Budget Room, 1 King Bed (Mountain View)",
                        ...
                    },
                    new Room()
                    {
                        Description = "Deluxe Room, 2 Double Beds (City View)",
                        ...
                    }
                }
            }),
        IndexDocumentsAction.Upload(
            new Hotel()
            {
                HotelId = "2",
                HotelName = "Twin Dome Motel",
                ...
                {
                    StreetAddress = "140 University Town Center Dr",
                    ...
                },
                Rooms = new Room[]
                {
                    new Room()
                    {
                        Description = "Suite, 2 Double Beds (Mountain View)",
                        ...
                    },
                    new Room()
                    {
                        Description = "Standard Room, 1 Queen Bed (City View)",
                        ...
                    },
                    new Room()
                    {
                        Description = "Budget Room, 1 King Bed (Waterfront View)",
                        ...
                    }
                }
            }),
        IndexDocumentsAction.Upload(
            new Hotel()
            {
                HotelId = "3",
                HotelName = "Triple Landscape Hotel",
                ...
                Address = new Address()
                {
                    StreetAddress = "3393 Peachtree Rd",
                    ...
                },
                Rooms = new Room[]
                {
                    new Room()
                    {
                        Description = "Standard Room, 2 Queen Beds (Amenities)",
                        ...
                    },
                    new Room ()
                    {
                        Description = "Standard Room, 2 Double Beds (Waterfront View)",
                        ...
                    },
                    new Room()
                    {
                        Description = "Deluxe Room, 2 Double Beds (Cityside)",
                        ...
                    }
                }
            }
        };

    try
    {
        IndexDocumentsResult result = searchClient.IndexDocuments(batch);
    }
    catch (Exception)
    {
        // Sometimes when your Search service is under load, indexing will fail for some of the documents in
        // the batch. Depending on your application, you can take compensating actions like delaying and
        // retrying. For this simple demo, we just log the failed document keys and continue.
        Console.WriteLine("Failed to index some of the documents: {0}");
    }

    Console.WriteLine("Waiting for documents to be indexed...\n");
    Thread.Sleep(2000);

Tato metoda má čtyři části. První vytvoří pole tří Hotel objektů s třemi Room objekty, které budou sloužit jako vstupní data pro nahrání do indexu. Tato data jsou pro jednoduchost pevně zakódovaná. Ve skutečné aplikaci budou data pravděpodobně pocházet z externího zdroje dat, jako je databáze SQL.

Druhá část vytvoří IndexDocumentsBatch obsahující dokumenty. Zadáte operaci, kterou chcete použít pro dávku v době, kdy ji vytvoříte, v tomto případě zavoláním IndexDocumentsAction.Upload. Dávka se pak nahraje do indexu Azure AI Search metodou IndexDocuments .

Poznámka:

V tomto příkladu právě nahráváme dokumenty. Pokud chcete sloučit změny do existujících dokumentů nebo odstranit dokumenty, můžete dávky vytvořit voláním IndexDocumentsAction.Merge, IndexDocumentsAction.MergeOrUploadnebo IndexDocumentsAction.Delete místo toho. Můžete také kombinovat různé operace v jedné dávce voláním IndexBatch.New, která přebírá kolekci IndexDocumentsAction objektů, z nichž každá dává Službě Azure AI Search pokyn k provedení konkrétní operace v dokumentu. Každou z nich IndexDocumentsAction můžete vytvořit pomocí vlastní operace voláním odpovídající metody, například IndexDocumentsAction.Merge, IndexAction.Uploadatd.

Třetí část této metody je blok catch, který zpracovává důležitý případ chyby pro indexování. Pokud se službě Search nepodaří indexovat některé dokumenty v dávce, RequestFailedException vyvolá se vyvolá se. K výjimce může dojít v případě, že indexujete dokumenty, když je služba zatížená velkým zatížením. Důrazně doporučujeme v kódu explicitně zpracovávat tento případ. Indexování dokumentů, které selhaly, můžete odložit a poté zkusit znovu, nebo v závislosti na požadavcích vaší aplikace na konzistenci dat provést něco jiného. Alternativou je použít SearchIndexingBufferedSender pro inteligentní dávkování, automatické vyprázdnění a opakování pro neúspěšné akce indexování. Další kontext najdete v tomto příkladu .

Nakonec metoda UploadDocuments zpožďuje dvě sekundy. Indexování probíhá asynchronně ve vyhledávací službě, takže ukázková aplikace musí chvíli počkat, aby se zajistilo, že jsou dokumenty k dispozici pro vyhledávání. Tato odložení se obvykle používají pouze v ukázkových aplikacích a při testech.

Volání UploadDocuments v Main()

Následující fragment kódu nastaví instanci SearchClient použití GetSearchClient metody indexClient. IndexClient na svých požadavcích používá klíč rozhraní API pro správu, který se vyžaduje pro načítání nebo aktualizaci dokumentů.

Alternativním přístupem je přímé volání SearchClient předávající klíč rozhraní API správce .AzureKeyCredential

SearchClient searchClient = indexClient.GetSearchClient(indexName);

Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(searchClient);

Spouštění dotazů

Nejprve nastavte SearchClient koncový bod služby a klíč rozhraní API pro dotazy z appsettings.json:

private static SearchClient CreateSearchClientForQueries(string indexName, IConfigurationRoot configuration)
{
    string searchServiceEndPoint = configuration["SearchServiceEndPoint"];
    string queryApiKey = configuration["SearchServiceQueryApiKey"];

    SearchClient searchClient = new SearchClient(new Uri(searchServiceEndPoint), indexName, new AzureKeyCredential(queryApiKey));
    return searchClient;
}

Za druhé definujte metodu, která odešle požadavek na dotaz.

Pokaždé, když metoda spustí dotaz, vytvoří nový SearchOptions objekt. Tento objekt slouží k určení dalších možností dotazu, jako je řazení, filtrování, stránkování a fasetování. V této metodě nastavujeme Filtervlastnost a SelectOrderBy vlastnost pro různé dotazy. Další informace o syntaxi výrazu vyhledávacího dotazu najdete v jednoduché syntaxi dotazu.

Dalším krokem je spuštění dotazu. Spuštění hledání se provádí pomocí SearchClient.Search metody. Pro každý dotaz předejte hledaný text, který se použije jako řetězec (nebo "*" pokud neexistuje žádný hledaný text), a možnosti hledání vytvořené dříve. Zadáme Hotel také jako parametr SearchClient.Searchtypu , který sadě SDK říká, aby deserializovat dokumenty ve výsledcích hledání na objekty typu Hotel.

private static void RunQueries(SearchClient searchClient)
{
    SearchOptions options;
    SearchResults<Hotel> results;

    Console.WriteLine("Query 1: Search for 'motel'. Return only the HotelName in results:\n");

    options = new SearchOptions();
    options.Select.Add("HotelName");

    results = searchClient.Search<Hotel>("motel", options);

    WriteDocuments(results);

    Console.Write("Query 2: Apply a filter to find hotels with rooms cheaper than $100 per night, ");
    Console.WriteLine("returning the HotelId and Description:\n");

    options = new SearchOptions()
    {
        Filter = "Rooms/any(r: r/BaseRate lt 100)"
    };
    options.Select.Add("HotelId");
    options.Select.Add("Description");

    results = searchClient.Search<Hotel>("*", options);

    WriteDocuments(results);

    Console.Write("Query 3: Search the entire index, order by a specific field (lastRenovationDate) ");
    Console.Write("in descending order, take the top two results, and show only hotelName and ");
    Console.WriteLine("lastRenovationDate:\n");

    options =
        new SearchOptions()
        {
            Size = 2
        };
    options.OrderBy.Add("LastRenovationDate desc");
    options.Select.Add("HotelName");
    options.Select.Add("LastRenovationDate");

    results = searchClient.Search<Hotel>("*", options);

    WriteDocuments(results);

    Console.WriteLine("Query 4: Search the HotelName field for the term 'hotel':\n");

    options = new SearchOptions();
    options.SearchFields.Add("HotelName");

    //Adding details to select, because "Location" isn't supported yet when deserializing search result to "Hotel"
    options.Select.Add("HotelId");
    options.Select.Add("HotelName");
    options.Select.Add("Description");
    options.Select.Add("Category");
    options.Select.Add("Tags");
    options.Select.Add("ParkingIncluded");
    options.Select.Add("LastRenovationDate");
    options.Select.Add("Rating");
    options.Select.Add("Address");
    options.Select.Add("Rooms");

    results = searchClient.Search<Hotel>("hotel", options);

    WriteDocuments(results);
}

Za třetí definujte metodu, která zapíše odpověď a vytiskne každý dokument do konzoly:

private static void WriteDocuments(SearchResults<Hotel> searchResults)
{
    foreach (SearchResult<Hotel> result in searchResults.GetResults())
    {
        Console.WriteLine(result.Document);
    }

    Console.WriteLine();
}

Volání RunQueries v Main()

SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

Console.WriteLine("{0}", "Running queries...\n");
RunQueries(indexClientForQueries);

Prozkoumání konstruktorů dotazů

Pojďme se podrobněji podívat na jednotlivé dotazy. Tady je kód pro spuštění prvního dotazu:

options = new SearchOptions();
options.Select.Add("HotelName");

results = searchClient.Search<Hotel>("motel", options);

WriteDocuments(results);

V tomto případě hledáme v celém indexu slovo "motel" v libovolném prohledávatelném poli a chceme načíst pouze názvy hotelů, jak je uvedeno v Select možnosti. Tady jsou výsledky:

Name: Secret Point Motel

Name: Twin Dome Motel

Ve druhém dotazu pomocí filtru vyberte místnosti s noční sazbou nižší než 100 USD. Ve výsledcích vrátí pouze ID hotelu a popis:

options = new SearchOptions()
{
    Filter = "Rooms/any(r: r/BaseRate lt 100)"
};
options.Select.Add("HotelId");
options.Select.Add("Description");

results = searchClient.Search<Hotel>("*", options);

Výše uvedený dotaz používá k filtrování dokumentů v indexu výraz Rooms/any(r: r/BaseRate lt 100)OData$filter. Tento operátor používá jakýkoli operátor k použití BaseRate lt 100 pro každou položku v kolekci Rooms. Další informace najdete v tématu Syntaxe filtru OData.

Ve třetím dotazu najděte nejlepší dva hotely, které byly naposledy rekonstruovány, a ukažte název hotelu a datum poslední renovace. Tady je kód:

options =
    new SearchOptions()
    {
        Size = 2
    };
options.OrderBy.Add("LastRenovationDate desc");
options.Select.Add("HotelName");
options.Select.Add("LastRenovationDate");

results = searchClient.Search<Hotel>("*", options);

WriteDocuments(results);

V posledním dotazu vyhledejte všechny názvy hotelů, které odpovídají slovu "hotel":

options.Select.Add("HotelId");
options.Select.Add("HotelName");
options.Select.Add("Description");
options.Select.Add("Category");
options.Select.Add("Tags");
options.Select.Add("ParkingIncluded");
options.Select.Add("LastRenovationDate");
options.Select.Add("Rating");
options.Select.Add("Address");
options.Select.Add("Rooms");

results = searchClient.Search<Hotel>("hotel", options);

WriteDocuments(results);

Tato část uzavírá tento úvod do sady .NET SDK, ale nezastavujte ji tady. V další části najdete další zdroje informací o programování pomocí služby Azure AI Search.

Další kroky