Dela via


Använda Azure.Search.Documents i ett .NET-program

Den här artikeln beskriver hur du skapar och hanterar sökobjekt med hjälp av C# och klientbiblioteket Azure.Search.Documents (version 11) i Azure SDK för .NET.

Om version 11

Azure SDK för .NET innehåller ett Azure.Search.Documents-klientbibliotek från Azure SDK-teamet som är funktionellt likvärdigt med det tidigare klientbiblioteket, Microsoft.Azure.Search. Version 11 är mer konsekvent när det gäller Azure-programmering. Några exempel är AzureKeyCredential nyckelautentisering och System.Text.Json.Serialization för JSON-serialisering.

Precis som med tidigare versioner kan du använda det här biblioteket för att:

  • Skapa och hantera sökindex, datakällor, indexerare, kompetensuppsättningar och synonymkartor
  • Läsa in och hantera sökdokument i ett index
  • Kör frågor, allt utan att behöva ta itu med informationen om HTTP och JSON
  • Anropa och hantera AI-berikande (kompetensuppsättningar) och utdata

Biblioteket distribueras som ett enda NuGet-paket som innehåller alla API:er som används för programmatisk åtkomst till en söktjänst.

Klientbiblioteket definierar klasser som SearchIndex, SearchFieldoch SearchDocumentsamt åtgärder som SearchIndexClient.CreateIndex och SearchClient.SearchSearchIndexClient klasserna och SearchClient . Dessa klasser är ordnade i följande namnområden:

Version 11 är avsedd för specifikationen för söktjänsten 2020-06-30.

Klientbiblioteket tillhandahåller inte tjänsthanteringsåtgärder, till exempel att skapa och skala söktjänster och hantera API-nycklar. Om du behöver hantera dina sökresurser från ett .NET-program använder du biblioteket Microsoft.Azure.Management.Search i Azure SDK för .NET.

Uppgradera till v11

Om du har använt den tidigare versionen av .NET SDK och vill uppgradera till den aktuella allmänt tillgängliga versionen läser du Uppgradera till Azure AI Search .NET SDK version 11.

SDK-krav

  • Visual Studio 2019 eller senare.

  • Din egen Azure AI-tjänsten Search. För att kunna använda SDK behöver du namnet på din tjänst och en eller flera API-nycklar. Skapa en tjänst i portalen om du inte har någon.

  • Ladda ned NuGet-paketet med Verktyg >NuGet Package Manager>Hantera NuGet-paket för lösning i Visual Studio. Sök efter paketnamnet Azure.Search.Documents.

Azure SDK för .NET överensstämmer med .NET Standard 2.0.

Exempelprogram

Den här artikeln lär sig genom exempel att förlita sig på DotNetHowTo-kodexemplet på GitHub för att illustrera grundläggande begrepp i Azure AI Search och hur du skapar, läser in och frågar ett sökindex.

För resten av den här artikeln antar du att ett nytt index med namnet hotels, fyllt med några dokument, med flera frågor som matchar resultaten.

I följande exempel visas huvudprogrammet med det övergripande flödet:

// 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();
}

Nästa är en partiell skärmbild av utdata, förutsatt att du kör det här programmet med ett giltigt tjänstnamn och API-nycklar:

Skärmbild av Console.WriteLine-utdata från exempelprogrammet.

Klienttyper

Klientbiblioteket använder tre klienttyper för olika åtgärder: SearchIndexClient för att skapa, uppdatera eller ta bort index, SearchClient läsa in eller köra frågor mot ett index och SearchIndexerClient arbeta med indexerare och kompetensuppsättningar. Den här artikeln fokuserar på de två första.

Som minst kräver alla klienter tjänstnamn eller slutpunkt och en API-nyckel. Det är vanligt att ange den här informationen i en konfigurationsfil, ungefär som i appsettings.json-filen i Exempelprogrammet DotNetHowTo. Om du vill läsa från konfigurationsfilen lägger du till using Microsoft.Extensions.Configuration; i programmet.

Följande instruktion skapar den indexklient som används för att skapa, uppdatera eller ta bort index. Det tar en tjänstslutpunkt och en api-nyckel för administratörer.

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

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

Nästa instruktion skapar sökklienten som används för att läsa in dokument eller köra frågor. SearchClient kräver ett index. Du behöver en administratörs-API-nyckel för att läsa in dokument, men du kan använda en fråge-API-nyckel för att köra frågor.

string indexName = configuration["SearchIndexName"];

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

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

Kommentar

Om du anger en ogiltig nyckel för importåtgärden (till exempel en frågenyckel där en administratörsnyckel krävdes) SearchClient genererar den en CloudException med felmeddelandet Förbjuden första gången du anropar en åtgärdsmetod på den. Om detta händer dig dubbelkollar du API-nyckeln.

Ta bort indexet

I de tidiga utvecklingsstadierna kanske du vill inkludera en DeleteIndex instruktion för att ta bort ett index för pågående arbete så att du kan återskapa det med en uppdaterad definition. Exempelkoden för Azure AI Search innehåller ofta ett borttagningssteg så att du kan köra exemplet igen.

Följande rad anropar DeleteIndexIfExists:

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

Den här metoden använder angiven SearchIndexClient för att kontrollera om indexet finns och tar i så fall bort det:

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.");

Kommentar

Exempelkoden i den här artikeln använder synkrona metoder för enkelhetens skull, men du bör använda asynkrona metoder i dina egna program för att hålla dem skalbara och dynamiska. I den föregående metoden kan du till exempel använda DeleteIndexAsync i stället för DeleteIndex.

Skapa ett index

Du kan använda SearchIndexClient för att skapa ett index.

Följande metod skapar ett nytt SearchIndex objekt med en lista över SearchField objekt som definierar schemat för det nya indexet. Varje fält har ett namn, en datatyp och flera attribut som definierar dess sökbeteende.

Fält kan definieras från en modellklass med hjälp av FieldBuilder. Klassen FieldBuilder använder reflektion för att skapa en lista över SearchField objekt för indexet genom att undersöka de offentliga egenskaperna och attributen för den angivna Hotel modellklassen. Vi tar en närmare titt på Hotel klassen senare.

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);
}

Förutom fält kan du också lägga till bedömningsprofiler, förslagsgivare eller CORS-alternativ i indexet (dessa parametrar utelämnas från exemplet för korthet). Du hittar mer information om SearchIndex objektet och dess komponenter i listan SearchIndex-egenskaper samt i REST API-referensen.

Kommentar

Du kan alltid skapa listan med Field objekt direkt i stället för att använda FieldBuilder om det behövs. Du kanske till exempel inte vill använda en modellklass eller så kan du behöva använda en befintlig modellklass som du inte vill ändra genom att lägga till attribut.

Anropa CreateIndex i Main()

Main skapar ett nytt hotellindex genom att anropa föregående metod:

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

Använda en modellklass för datarepresentation

DotNetHowTo-exemplet använder modellklasser för datastrukturerna Hotell, Adress och Rum . Hotel referenser Address, en komplex typ på en nivå (ett fält med flera delar) och Room (en samling fält i flera delar).

Du kan använda dessa typer för att skapa och läsa in indexet och strukturera svaret från en fråga:

// 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();
}

En annan metod är att lägga till fält i ett index direkt. I följande exempel visas bara några få fält.

 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 }
         }
 };

Fältdefinitioner

Din datamodell i .NET och dess motsvarande indexschema bör ha stöd för den sökupplevelse som du vill ge till slutanvändaren. Varje objekt på den översta nivån i .NET, till exempel ett sökdokument i ett sökindex, motsvarar ett sökresultat som du skulle presentera i användargränssnittet. I ett hotellsökningsprogram kanske slutanvändarna till exempel vill söka efter hotellnamn, hotellets funktioner eller egenskaperna hos ett visst rum.

I varje klass definieras ett fält med en datatyp och attribut som avgör hur det används. Namnet på varje offentlig egenskap i varje klass mappar till ett fält med samma namn i indexdefinitionen.

Ta en titt på följande kodfragment som hämtar flera fältdefinitioner från klassen Hotell. Observera att Address och Rooms är C#-typer med egna klassdefinitioner (se exempelkoden om du vill visa dem). Båda är komplexa typer. Mer information finns i Så här modellerar du komplexa typer.

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; }

Välj en fältklass

När du definierar fält kan du använda basklassen SearchField eller använda derivathjälpmodeller som fungerar som mallar med förkonfigurerade egenskaper.

Exakt ett fält i indexet måste fungera som dokumentnyckel (IsKey = true). Det måste vara en sträng och måste unikt identifiera varje dokument. Den måste också ha IsHidden = true, vilket innebär att den inte kan visas i sökresultaten.

Fälttyp Beskrivning och användning
SearchField Basklass, med de flesta egenskaper inställda på null, förutom Name vad som krävs och AnalyzerName som standard är Standard Lucene.
SimpleField Hjälpmodell. Kan vara vilken datatyp som helst, är alltid inte sökbar (den ignoreras för fulltextsökningsfrågor) och kan hämtas (den är inte dold). Andra attribut är inaktiverade som standard, men kan aktiveras. Du kan använda ett SimpleField för dokument-ID eller fält som endast används i filter, fasetter eller bedömningsprofiler. I så fall bör du tillämpa eventuella attribut som är nödvändiga för scenariot, till exempel IsKey = true för ett dokument-ID. Mer information finns i SimpleFieldAttribute.cs i källkoden.
SearchableField Hjälpmodell. Måste vara en sträng och är alltid sökbar och hämtningsbar. Andra attribut är inaktiverade som standard, men kan aktiveras. Eftersom den här fälttypen är sökbar stöder den synonymer och det fullständiga komplementet av analysverktygsegenskaper. Mer information finns i SearchableFieldAttribute.cs i källkoden.

Oavsett om du använder det grundläggande SearchField API:et eller någon av hjälpmodellerna måste du uttryckligen aktivera attribut för filter, fasetter och sortering. Till exempel måste IsFilterable, IsSortable och IsFacetable uttryckligen tillskrivas, som du ser i föregående exempel.

Lägga till fältattribut

Observera hur varje fält är dekorerat med attribut som IsFilterable, IsSortable, IsKeyoch AnalyzerName. Dessa attribut mappas direkt till motsvarande fältattribut i ett Azure AI Search-index. Klassen FieldBuilder använder dessa egenskaper för att konstruera fältdefinitioner för indexet.

Mappning av fälttyp

.NET-typerna av egenskaperna mappas till motsvarande fälttyper i indexdefinitionen. Exempelvis mappar Category-strängegenskapen till category-fältet, som är av typen Edm.String. Det finns liknande typmappningar mellan bool?, Edm.Boolean, DateTimeOffset?och Edm.DateTimeOffset och så vidare.

Såg du fastigheten SmokingAllowed ?

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

Attributet JsonIgnore för den här egenskapen anger FieldBuilder att det inte ska serialiseras till indexet som ett fält. Det här är ett bra sätt att skapa beräknade egenskaper på klientsidan som du kan använda som hjälp i ditt program. I det här fallet återspeglar egenskapen SmokingAllowed om någon Room i Rooms samlingen tillåter rökning. Om alla är falska indikerar det att hela hotellet inte tillåter rökning.

Läs in ett index

Nästa steg i fyller i Main det nyskapade hotellindexet . Den här indexpopulationen görs med följande metod: (Viss kod ersätts med ... i illustrationssyfte. Se den fullständiga exempellösningen för den fullständiga datapopulationskoden.)

private static void UploadDocuments(SearchClient searchClient)
{
    IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create(
        IndexDocumentsAction.Upload(
            new Hotel()
            {
                HotelId = "1",
                HotelName = "Stay-Kay City Hotel",
                ...
                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 = "Old Century Hotel",
                ...
                {
                    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 = "Gastronomic 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);

Den här metoden har fyra delar. Den första skapar en matris med tre Hotel objekt var och en med tre Room objekt som fungerar som indata att ladda upp till indexet. Dessa data är hårdkodade för enkelhetens skull. I ett faktiskt program kommer data troligen från en extern datakälla, till exempel en SQL-databas.

Den andra delen skapar en IndexDocumentsBatch som innehåller dokumenten. Du anger den åtgärd som du vill tillämpa på batchen när du skapar den, i det här fallet genom att anropa IndexDocumentsAction.Upload. Batchen laddas sedan upp till Azure AI Search-indexet med metoden IndexDocuments .

Kommentar

I det här exemplet laddar du bara upp dokument. Om du vill sammanfoga ändringar i befintliga dokument eller ta bort dokument kan du skapa batchar genom att anropa IndexDocumentsAction.Merge, IndexDocumentsAction.MergeOrUploadeller IndexDocumentsAction.Delete i stället. Du kan också blanda olika åtgärder i en enda batch genom att anropa IndexBatch.New, som tar en samling IndexDocumentsAction objekt, som var och en uppmanar Azure AI Search att utföra en viss åtgärd i ett dokument. Du kan skapa var och en IndexDocumentsAction med sin egen åtgärd genom att anropa motsvarande metod, till exempel IndexDocumentsAction.Merge, IndexAction.Uploadoch så vidare.

Den tredje delen av den här metoden är ett catch-block som hanterar ett viktigt felfall för indexering. Om söktjänsten inte kan indexera vissa dokument i batchen genereras en RequestFailedException . Ett undantag kan inträffa om du indexerar dokument medan tjänsten är hårt belastad. Vi rekommenderar starkt att du uttryckligen hanterar den här situationen i din kod. Du kan fördröja och sedan försöka indexera dokumentet som misslyckades igen eller så kan du logga och fortsätta som i exemplet, eller göra något annat beroende på programmets krav på datakonsekvens. Ett alternativ är att använda SearchIndexingBufferedSender för intelligent batchbearbetning, automatisk tömning och återförsök för misslyckade indexeringsåtgärder. Mer kontext finns i exemplet SearchIndexingBufferedSender.

Slutligen fördröjs metoden i UploadDocuments två sekunder. Indexering sker asynkront i söktjänsten, så exempelprogrammet måste vänta en kort stund för att säkerställa att dokumenten är tillgängliga för sökning. Fördröjningar som den här är normalt endast nödvändiga i demonstrationer, tester och exempelprogram.

Anropa UploadDocuments i Main()

Följande kodfragment konfigurerar en instans av med hjälp GetSearchClient av SearchClient metoden indexClient. IndexClient använder en administratörs-API-nyckel för sina begäranden, vilket krävs för att läsa in eller uppdatera dokument.

En alternativ metod är att anropa SearchClient direkt och skicka in en administratörs-API-nyckel på AzureKeyCredential.

SearchClient searchClient = indexClient.GetSearchClient(indexName);

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

Köra frågor

Konfigurera först en SearchClient som läser tjänstslutpunkten och frågar API-nyckeln från appsettings.json:

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

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

För det andra definierar du en metod som skickar en frågebegäran.

Varje gång metoden kör en fråga skapas ett nytt SearchOptions objekt. Det här objektet används för att ange ytterligare alternativ för frågan, till exempel sortering, filtrering, växling och fasettering. I den här metoden ställer vi in Filteregenskapen , Selectoch OrderBy för olika frågor. Mer information om syntaxen för sökfrågeuttryck finns i Enkel frågesyntax.

Nästa steg är frågekörning. Sökningen körs med hjälp av SearchClient.Search metoden . För varje fråga skickar du söktexten som ska användas som en sträng (eller "*" om det inte finns någon söktext), plus de sökalternativ som skapades tidigare. Vi anger Hotel även som typparameter för SearchClient.Search, som instruerar SDK:t att deserialisera dokument i sökresultaten till objekt av typen 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);
}

För det tredje definierar du en metod som skriver svaret och skriver ut varje dokument till konsolen:

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

    Console.WriteLine();
}

Anropa RunQueries i Main()

SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

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

Utforska frågekonstruktioner

Låt oss ta en närmare titt på var och en av frågorna i tur och ordning. Här är koden för att köra den första frågan:

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

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

WriteDocuments(results);

I det här fallet söker vi i hela indexet efter ordet motell i alla sökbara fält och vi vill bara hämta hotellnamnen enligt Select alternativet. Här är resultatet:

Name: Stay-Kay City Hotel

Name: Old Century Hotel

I den andra frågan använder du ett filter för att välja rum med ett nattpris på mindre än 100 USD. Returnera endast hotell-ID:t och beskrivningen i resultatet:

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

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

Den här frågan använder ett OData-uttryck $filter , Rooms/any(r: r/BaseRate lt 100), för att filtrera dokumenten i indexet. Den använder alla operatorer för att tillämpa "BaseRate lt 100" på varje objekt i samlingen Rum. Mer information finns i OData-filtersyntax.

I den tredje frågan hittar du de två bästa hotellen som har renoverats senast och visar hotellets namn och senaste renoveringsdatum. Här är koden:

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);

I den senaste frågan letar du upp alla hotellnamn som matchar ordet hotell:

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);

Det här avsnittet avslutar den här introduktionen till .NET SDK, men sluta inte här. I nästa avsnitt föreslås andra resurser för att lära dig mer om programmering med Azure AI Search.