Azure.Search.Documents gebruiken in een C# .NET-toepassing

In dit artikel wordt uitgelegd hoe u zoekobjecten maakt en beheert met behulp van C# en de clientbibliotheek Azure.Search.Documents (versie 11) in de Azure SDK voor .NET.

Over versie 11

Azure SDK voor .NET bevat een Azure.Search.Documents-clientbibliotheek van het Azure SDK-team dat functioneel gelijk is aan de vorige clientbibliotheek, Microsoft.Azure.Search. Versie 11 is consistenter wat betreft de programmeerbaarheid van Azure. Enkele voorbeelden zijn AzureKeyCredential sleutelverificatie en System.Text.Json.Serialization voor JSON-serialisatie.

Net als bij eerdere versies kunt u deze bibliotheek gebruiken voor het volgende:

  • Zoekindexen, gegevensbronnen, indexeerfuncties, vaardighedensets en synoniemenkaarten maken en beheren
  • Zoekdocumenten in een index laden en beheren
  • Query's uitvoeren, allemaal zonder dat u te maken hebt met de details van HTTP en JSON
  • AI-verrijking (vaardighedensets) en uitvoer aanroepen en beheren

De bibliotheek wordt gedistribueerd als één Azure.Search.Documents NuGet-pakket, dat alle API's bevat die worden gebruikt voor programmatische toegang tot een zoekservice.

De clientbibliotheek definieert klassen zoals SearchIndex, SearchFielden , evenals SearchDocumentbewerkingen zoals SearchIndexClient.CreateIndex en SearchClient.Search op de SearchIndexClient en SearchClient klassen. Deze klassen zijn ingedeeld in de volgende naamruimten:

Azure.Search.Documents (versie 11) is gericht op de specificatie van de zoekservice 2020-06-30.

De clientbibliotheek biedt geen servicebeheerbewerkingen, zoals het maken en schalen van zoekservices en het beheren van API-sleutels. Als u uw zoekbronnen wilt beheren vanuit een .NET-toepassing, gebruikt u de bibliotheek Microsoft.Azure.Management.Search in de Azure SDK voor .NET.

Upgraden naar v11

Als u de vorige versie van de .NET SDK hebt gebruikt en u een upgrade wilt uitvoeren naar de huidige algemeen beschikbare versie, raadpleegt u Upgraden naar Azure AI Search .NET SDK versie 11.

SDK-vereisten

Azure SDK voor .NET voldoet aan .NET Standard 2.0.

Voorbeeldtoepassing

In dit artikel leert u 'aan de hand van een voorbeeld', waarbij u afhankelijk bent van het DotNetHowTo-codevoorbeeld op GitHub om fundamentele concepten in Azure AI Search te illustreren, met name het maken, laden en opvragen van een zoekindex.

Voor de rest van dit artikel wordt ervan uitgegaan dat er een nieuwe index met de naam hotels wordt ingevuld, gevuld met enkele documenten, met verschillende query's die overeenkomen met de resultaten.

Hieronder ziet u het hoofdprogramma met de algehele stroom:

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

Hierna volgt een gedeeltelijke schermopname van de uitvoer, ervan uitgaande dat u deze toepassing uitvoert met een geldige servicenaam en API-sleutels:

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

Clienttypen

De clientbibliotheek maakt gebruik van drie clienttypen voor verschillende bewerkingen: SearchIndexClient indexen maken, bijwerken of verwijderen, SearchClient een index laden of er query's op uitvoeren en SearchIndexerClient werken met indexeerfuncties en vaardighedensets. Dit artikel richt zich op de eerste twee.

Voor alle clients is minimaal de servicenaam of het eindpunt en een API-sleutel vereist. Het is gebruikelijk om deze informatie op te geven in een configuratiebestand, vergelijkbaar met wat u in het appsettings.json bestand van de DotNetHowTo-voorbeeldtoepassing vindt. Als u het configuratiebestand wilt lezen, voegt u dit toe using Microsoft.Extensions.Configuration; aan uw programma.

Met de volgende instructie maakt u de indexclient die wordt gebruikt voor het maken, bijwerken of verwijderen van indexen. Er wordt een service-eindpunt en beheer-API-sleutel gebruikt.

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

Met de volgende instructie wordt de zoekclient gemaakt die wordt gebruikt om documenten te laden of query's uit te voeren. SearchClient vereist een index. U hebt een beheerders-API-sleutel nodig om documenten te laden, maar u kunt een query-API-sleutel gebruiken om query's uit te voeren.

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

Notitie

Als u een ongeldige sleutel opgeeft voor de importbewerking (bijvoorbeeld een querysleutel waarbij een beheersleutel is vereist), wordt het SearchClient foutbericht 'Verboden' gegenereerd CloudException wanneer u een bewerkingsmethode voor het eerst aanroept. Als dit gebeurt, controleert u de API-sleutel.

De index verwijderen

In de vroege ontwikkelingsfasen wilt u mogelijk een DeleteIndex instructie opnemen om een werk-in-voortgangsindex te verwijderen, zodat u deze opnieuw kunt maken met een bijgewerkte definitie. Voorbeeldcode voor Azure AI Search bevat vaak een verwijderingsstap, zodat u het voorbeeld opnieuw kunt uitvoeren.

De volgende regeloproepen DeleteIndexIfExists:

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

Deze methode gebruikt de opgegeven methode SearchIndexClient om te controleren of de index bestaat en als dit het volgende is, verwijdert u deze:

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

Notitie

De voorbeeldcode in dit artikel maakt gebruik van de synchrone methoden voor het gemak, maar u moet de asynchrone methoden in uw eigen toepassingen gebruiken om ze schaalbaar en responsief te houden. In de bovenstaande methode kunt u bijvoorbeeld in DeleteIndexAsync plaats van DeleteIndex.

Een index maken

U kunt een SearchIndexClient index maken.

Met de onderstaande methode maakt u een nieuw SearchIndex object met een lijst SearchField met objecten die het schema van de nieuwe index definiëren. Elk veld heeft een naam, gegevenstype en verschillende kenmerken waarmee het zoekgedrag wordt gedefinieerd.

Velden kunnen worden gedefinieerd vanuit een modelklasse met behulp van FieldBuilder. De FieldBuilder klasse gebruikt weerspiegeling om een lijst SearchField met objecten voor de index te maken door de openbare eigenschappen en kenmerken van de opgegeven Hotel modelklasse te onderzoeken. We gaan de Hotel klas later nader bekijken.

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

Naast velden kunt u ook scoreprofielen, suggesties of CORS-opties toevoegen aan de index (deze parameters worden weggelaten uit het voorbeeld voor beknoptheid). U vindt meer informatie over het SearchIndex-object en de bijbehorende onderdelen in de SearchIndex eigenschappenlijst, evenals in de REST API-verwijzing.

Notitie

U kunt de lijst Field met objecten altijd rechtstreeks maken in plaats van indien nodig te gebruiken FieldBuilder . U wilt bijvoorbeeld geen modelklasse gebruiken of u moet mogelijk een bestaande modelklasse gebruiken die u niet wilt wijzigen door kenmerken toe te voegen.

CreateIndex aanroepen in Main()

Main maakt een nieuwe index hotels door de bovenstaande methode aan te roepen:

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

Een modelklasse gebruiken voor gegevensweergave

Het DotNetHowTo-voorbeeld maakt gebruik van modelklassen voor de gegevensstructuren Hotel, Address en Room . Hotel verwijzingen Address, een complex type met één niveau (een meerdelig veld) en Room (een verzameling velden met meerdere delen).

U kunt deze typen gebruiken om de index te maken en te laden en om het antwoord van een query te structuren:

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

Een alternatieve benadering is het rechtstreeks toevoegen van velden aan een index. In het volgende voorbeeld ziet u slechts enkele velden.

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

Velddefinities

Uw gegevensmodel in .NET en het bijbehorende indexschema moeten de zoekervaring ondersteunen die u aan uw eindgebruiker wilt geven. Elk object op het hoogste niveau in .NET, zoals een zoekdocument in een zoekindex, komt overeen met een zoekresultaat dat u in uw gebruikersinterface zou presenteren. In een hotelzoektoepassing willen uw eindgebruikers bijvoorbeeld zoeken op hotelnaam, functies van het hotel of de kenmerken van een bepaalde kamer.

Binnen elke klasse wordt een veld gedefinieerd met een gegevenstype en kenmerken die bepalen hoe het wordt gebruikt. De naam van elke openbare eigenschap in elke klasse wordt toegewezen aan een veld met dezelfde naam in de indexdefinitie.

Bekijk het volgende codefragment waarmee verschillende velddefinities uit de klasse Hotel worden opgehaald. U ziet dat Adres- en ruimten C#-typen zijn met hun eigen klassedefinities (raadpleeg de voorbeeldcode als u ze wilt weergeven). Beide zijn complexe typen. Zie Complexe typen modelleren voor meer informatie.

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

Een veldklasse kiezen

Wanneer u velden definieert, kunt u de basisklasse SearchField gebruiken of afgeleide helpermodellen gebruiken die fungeren als 'sjablonen', met vooraf geconfigureerde eigenschappen.

Precies één veld in uw index moet fungeren als de documentsleutel (IsKey = true). Het moet een tekenreeks zijn en moet elk document uniek identificeren. Het is ook vereist om te hebben IsHidden = true, wat betekent dat het niet zichtbaar is in zoekresultaten.

Veldtype Beschrijving en gebruik
SearchField Basisklasse, waarbij de meeste eigenschappen zijn ingesteld op null, met uitzondering Name van wat vereist is, en AnalyzerName welke standaard is ingesteld op Standaard Lucene.
SimpleField Helpermodel. Dit kan elk gegevenstype zijn, is altijd niet doorzoekbaar (het wordt genegeerd voor zoekquery's in volledige tekst) en kan worden opgehaald (het is niet verborgen). Andere kenmerken zijn standaard uitgeschakeld, maar kunnen wel worden ingeschakeld. U kunt een SimpleField gebruiken voor document-id's of velden die alleen worden gebruikt in filters, facetten of scoreprofielen. Als dat het geval is, moet u ervoor zorgen dat u alle kenmerken toepast die nodig zijn voor het scenario, zoals IsKey = true voor een document-id. Zie SimpleFieldAttribute.cs in broncode voor meer informatie.
SearchableField Helpermodel. Moet een tekenreeks zijn en kan altijd worden doorzocht en opgehaald. Andere kenmerken zijn standaard uitgeschakeld, maar kunnen wel worden ingeschakeld. Omdat dit veldtype kan worden doorzocht, worden synoniemen en het volledige gamma van analyse-eigenschappen ondersteund. Zie SearchableFieldAttribute.cs in broncode voor meer informatie.

Ongeacht of u de basis-API van SearchField of een van de hulpmodellen gebruikt, u moet filter-, facet- en sorteerkenmerken expliciet inschakelen. Bijvoorbeeld IsFilterable, IsSortableen IsFacetable moet expliciet worden voorzien van een kenmerk, zoals weergegeven in het bovenstaande voorbeeld.

Veldkenmerken toevoegen

U ziet hoe elk veld is ingericht met kenmerken zoals IsFilterable, IsSortable, IsKeyen AnalyzerName. Deze kenmerken worden rechtstreeks toegewezen aan de bijbehorende veldkenmerken in een Azure AI Search-index. De FieldBuilder klasse gebruikt deze eigenschappen om velddefinities voor de index samen te stellen.

Toewijzing van veldtype

De .NET-typen van de eigenschappen worden toegewezen aan hun equivalente veldtypen in de indexdefinitie. De tekenreekseigenschap Category is bijvoorbeeld toegewezen aan het veld category van type Edm.String. Er zijn vergelijkbare typetoewijzingen tussen bool?, Edm.Boolean, DateTimeOffset?en Edm.DateTimeOffset dergelijke.

Heb je de SmokingAllowed woning gezien?

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

Het JsonIgnore kenmerk van deze eigenschap geeft aan dat het FieldBuilder niet als veld naar de index moet worden geserialiseerd. Dit is een uitstekende manier om berekende eigenschappen aan de clientzijde te maken die u kunt gebruiken als helpers in uw toepassing. In dit geval geeft de SmokingAllowed eigenschap aan of een Room in de Rooms collectie roken toestaat. Als alles onwaar is, geeft het aan dat het hele hotel roken niet toestaat.

Een index laden

In de volgende stap wordt Main de zojuist gemaakte 'hotels'-index ingevuld. Deze indexpopulatie wordt uitgevoerd in de volgende methode: (Sommige code is vervangen door '...' ter illustratie. Bekijk de volledige voorbeeldoplossing voor de volledige code voor gegevenspopulatie.)

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

Deze methode heeft vier delen. De eerste maakt een matrix van drie Hotel objecten met elk drie Room objecten die als invoergegevens fungeren om naar de index te uploaden. Deze gegevens zijn in code vastgelegd om het eenvoudig te maken. In een werkelijke toepassing komen gegevens waarschijnlijk uit een externe gegevensbron, zoals een SQL-database.

Het tweede deel maakt een IndexDocumentsBatch met de documenten. U geeft de bewerking op die u wilt toepassen op de batch op het moment dat u deze maakt, in dit geval door aan te roepen IndexDocumentsAction.Upload. De batch wordt vervolgens door de IndexDocuments methode geüpload naar de Azure AI Search-index.

Notitie

In dit voorbeeld uploaden we alleen documenten. Als u wijzigingen wilt samenvoegen in bestaande documenten of documenten wilt verwijderen, kunt u batches maken door aan te roepen IndexDocumentsAction.Merge, IndexDocumentsAction.MergeOrUploadof IndexDocumentsAction.Delete in plaats daarvan. U kunt ook verschillende bewerkingen in één batch combineren door het aanroepen IndexBatch.Newvan IndexDocumentsAction een verzameling objecten, die elk azure AI Search vertelt om een bepaalde bewerking uit te voeren op een document. U kunt elk IndexDocumentsAction met een eigen bewerking maken door de bijbehorende methode aan te roepen, zoals IndexDocumentsAction.Merge, IndexAction.Uploadenzovoort.

Het derde deel van deze methode is een catch-blok dat een belangrijke foutcase voor indexering afhandelt. Als uw zoekservice een aantal documenten in de batch niet kan indexeren, wordt er een RequestFailedException gegenereerd. Er kan een uitzondering optreden als u documenten indexeert terwijl uw service zwaar wordt belast. Wij raden u aan deze aanvraag expliciet in uw code te behandelen. U kunt de indexering van documenten die niet zijn geïndexeerd vertragen en vervolgens opnieuw uitvoeren, maar u kunt ook een logboek maken en doorgaan zoals in het voorbeeld. U kunt ook een andere bewerking uitvoeren, afhankelijk van de vereisten omtrent de gegevensconsistentie van de toepassing. Een alternatief is het gebruik van SearchIndexingBufferedSender voor intelligente batchverwerking, automatisch leegmaken en nieuwe pogingen voor mislukte indexeringsacties. Zie dit voorbeeld voor meer context.

Ten slotte vertraagt de UploadDocuments methode twee seconden. Indexering vindt asynchroon plaats in uw zoekservice, dus de voorbeeldtoepassing moet even wachten om ervoor te zorgen dat de documenten beschikbaar zijn om te zoeken. Dergelijke vertragingen zijn doorgaans alleen nodig is demo’s, testen en voorbeeldtoepassingen.

UploadDocuments aanroepen in Main()

Met het volgende codefragment wordt een exemplaar ingesteld van SearchClient het gebruik van de GetSearchClient methode indexClient. De indexClient gebruikt een beheer-API-sleutel voor de aanvragen. Dit is vereist voor het laden of vernieuwen van documenten.

Een alternatieve benadering is om rechtstreeks aan te roepen SearchClient , waarbij een beheerders-API-sleutel wordt doorgegeven aan AzureKeyCredential.

SearchClient searchClient = indexClient.GetSearchClient(indexName);

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

Query's uitvoeren

Stel eerst een SearchClient service-eindpunt in en query-API-sleutel uit 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;
}

Definieer ten tweede een methode waarmee een queryaanvraag wordt verzonden.

Telkens wanneer de methode een query uitvoert, wordt er een nieuw SearchOptions object gemaakt. Dit object wordt gebruikt om extra opties voor de query op te geven, zoals sorteren, filteren, pagien en facet. In deze methode stellen we de Filtereigenschap en SelectOrderBy de eigenschap voor verschillende query's in. Voor meer informatie over de syntaxis van de zoekquery-expressie, eenvoudige querysyntaxis.

De volgende stap is het uitvoeren van query's. Het uitvoeren van de zoekopdracht wordt uitgevoerd met behulp van de SearchClient.Search methode. Geef voor elke query de zoektekst door die moet worden gebruikt als een tekenreeks (of "*" als er geen zoektekst is), plus de zoekopties die u eerder hebt gemaakt. We geven Hotel ook op als de typeparameter, SearchClient.Searchwaarmee de SDK documenten in de zoekresultaten moet deserialiseren in objecten van het type 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);
}

Definieer ten derde een methode waarmee het antwoord wordt geschreven, waarbij elk document naar de console wordt afgedrukt:

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

    Console.WriteLine();
}

RunQueries aanroepen in Main()

SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

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

Queryconstructies verkennen

Laten we elk van de query's eens nader bekijken. Dit is de code voor het uitvoeren van de eerste query:

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

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

WriteDocuments(results);

In dit geval zoeken we de hele index naar het woord 'motel' in een doorzoekbaar veld en willen we alleen de hotelnamen ophalen, zoals opgegeven door de Select optie. Dit zijn de resultaten:

Name: Secret Point Motel

Name: Twin Dome Motel

Gebruik in de tweede query een filter om ruimten te selecteren met een nachttarief van minder dan $ 100. Retourneer alleen de hotel-id en beschrijving in de resultaten:

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

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

In de bovenstaande query wordt een OData-expressie $filterRooms/any(r: r/BaseRate lt 100)gebruikt om de documenten in de index te filteren. Hierbij wordt elke operator gebruikt om de BaseRate lt 100 toe te passen op elk item in de verzameling Ruimten. Zie OData-filtersyntaxis voor meer informatie.

Zoek in de derde query de top twee hotels die het laatst zijn gerenoveerd en toon de naam van het hotel en de laatste renovatiedatum. Hier volgt de code:

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

Zoek in de laatste query alle hotelnamen die overeenkomen met het woord '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);

In deze sectie wordt deze inleiding tot de .NET SDK afgesloten, maar stop hier niet. In de volgende sectie worden andere resources voorgesteld voor meer informatie over programmeren met Azure AI Search.

Volgende stappen