Cara menggunakan Azure.Search.Documents dalam Aplikasi C# .NET

Artikel ini menjelaskan cara membuat dan mengelola objek pencarian menggunakan C# dan pustaka klien Azure.Search.Documents (versi 11) di Azure SDK untuk .NET.

Tentang Versi 11

Azure SDK untuk .NET menyertakan pustaka klien Azure.Search.Documents dari tim Azure SDK yang secara fungsional setara dengan pustaka klien sebelumnya, Microsoft.Azure.Search. Versi 11 lebih konsisten dalam hal kemampuan pemrograman Azure. Beberapa contoh termasuk autentikasi kunci AzureKeyCredential, dan System.Text.Json.Serialization untuk serialisasi JSON.

Seperti versi sebelumnya, Anda bisa menggunakan pustaka ini untuk:

  • Membuat dan mengelola indeks pencarian, sumber data, pengindeks, keterampilan, dan peta sinonim
  • Memuat dan mengelola dokumen pencarian dalam indeks
  • Jalankan kueri, semua tanpa harus berurusan dengan detail HTTP dan JSON
  • Memanggil dan mengelola pengayaan AI (set keterampilan) dan output

Library didistribusikan sebagai satu paket Azure.Search.DocNuGet, yang mencakup semua API yang digunakan untuk akses terprogram ke layanan pencarian.

Library klien mendefinisikan kelas seperti SearchIndex, SearchField, dan SearchDocument, serta operasi seperti SearchIndexClient.CreateIndex dan SearchClient.Search pada kelas SearchIndexClient dan SearchClient. Kelas ini diatur ke namespace berikut:

Azure.Search.Documents (versi 11) menargetkan spesifikasi layanan pencarian 2020-06-30.

Pustaka klien tidak menyediakan operasi manajemen layanan, seperti membuat dan menskalakan layanan pencarian dan mengelola kunci API. Jika Anda perlu mengelola sumber daya pencarian dari aplikasi .NET, gunakan pustaka Microsoft.Azure.Management.Search di Azure SDK untuk .NET.

Tingkatkan ke v11

Jika Anda telah menggunakan versi .NET SDK sebelumnya dan ingin memutakhirkan ke versi saat ini yang tersedia secara umum, lihat Meningkatkan ke Azure AI Search .NET SDK versi 11.

Persyaratan SDK

  • Visual Studio 2019 atau versi yang lebih baru.

  • Layanan Pencarian Azure AI Anda sendiri. Untuk menggunakan SDK, Anda memerlukan nama layanan dan satu atau beberapa kunci API. Buat layanan di portal jika Anda tidak memilikinya.

  • Unduh paket Azure.Search.Documents menggunakan Peralatan>Pengelola Paket NuGet>Kelola Paket NuGet untuk Solusi di Visual Studio. Cari nama paket Azure.Search.Documents.

Azure SDK untuk .NET sesuai dengan .NET Standard 2.0.

Contoh aplikasi

Artikel ini "mengajarkan berdasarkan contoh", mengandalkan contoh kode DotNetHowTo di GitHub untuk mengilustrasikan konsep dasar dalam Azure AI Search - khususnya, cara membuat, memuat, dan mengkueri indeks pencarian.

Untuk artikel lainnya, asumsikan indeks baru bernama "hotel", diisi dengan beberapa dokumen, dengan beberapa kueri yang cocok dengan hasil.

Di bawah ini adalah program utama, menunjukkan alur keseluruhan:

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

Berikutnya adalah tangkapan layar parsial dari output, dengan asumsi Anda menjalankan aplikasi ini dengan nama layanan dan kunci API yang valid:

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

Jenis klien

Pustaka klien menggunakan tiga jenis klien untuk berbagai operasi: SearchIndexClient untuk membuat, memperbarui, atau menghapus indeks, SearchClient memuat atau mengkueri indeks, dan SearchIndexerClient untuk bekerja dengan pengindeks dan keterampilan. Artikel ini berfokus pada dua yang pertama.

Minimal, semua klien memerlukan nama layanan atau titik akhir, dan kunci API. Adalah umum untuk memberikan informasi ini dalam file konfigurasi, mirip dengan apa yang Anda temukan dalam file appsettings.json pada sampel aplikasi sampel DotNetHowTo. Untuk membaca dari berkas konfigurasi, tambahkan using Microsoft.Extensions.Configuration; ke program Anda.

Pernyataan berikut membuat klien indeks yang digunakan untuk membuat, memperbarui, atau menghapus indeks. Dibutuhkan titik akhir layanan dan kunci API admin.

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

Pernyataan berikutnya membuat klien pencarian yang digunakan untuk memuat dokumen atau menjalankan kueri. SearchClient membutuhkan indeks. Anda memerlukan kunci API admin untuk memuat dokumen, tetapi Anda dapat menggunakan kunci API kueri untuk menjalankan kueri.

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

Catatan

Jika Anda memberikan kunci yang tidak valid untuk operasi impor (misalnya, kunci kueri tempat kunci admin diperlukan), SearchClient akan melemparkan CloudException pesan kesalahan "Terlarang" saat pertama kali Anda memanggil metode operasi di atasnya. Jika ini terjadi pada Anda, periksa kembali kunci API.

Menghapus indeks

Pada tahap awal pengembangan, Anda mungkin ingin menyertakan pernyataan DeleteIndex untuk menghapus indeks dalam proses sehingga Anda dapat membuatnya kembali dengan definisi yang diperbarui. Kode sampel untuk Azure AI Search sering menyertakan langkah penghapusan sehingga Anda dapat menjalankan ulang sampel.

Baris berikut memanggil DeleteIndexIfExists:

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

Metode ini menggunakan SearchIndexClient yang diberikan untuk memeriksa apakah indeks ada, dan jika demikian, menghapusnya:

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

Catatan

Kode contoh dalam artikel ini menggunakan metode sinkron untuk kesederhanaan, tetapi Anda harus menggunakan metode asinkron dalam aplikasi Anda sendiri untuk menjaganya tetap dapat diskalakan dan responsif. Misalnya, dalam metode di atas Anda dapat menggunakan DeleteIndexAsync alih-alih DeleteIndex.

Buat indeks

Anda bisa menggunakan SearchIndexClient untuk membuat indeks.

Metode di bawah ini membuat objek SearchIndex baru dengan daftar objek SearchField yang menentukan skema indeks baru. Setiap bidang memiliki nama, jenis data, dan beberapa atribut yang menentukan perilaku pencariannya.

Bidang dapat ditentukan dari kelas model menggunakan FieldBuilder. Kelas FieldBuilder menggunakan refleksi untuk membuat daftar objek SearchField untuk indeks dengan menguji properti dan atribut publik dari kelas model Hotel yang diberikan. Anda selalu dapat membuat daftar kelas Hotel nanti.

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

Selain bidang, Anda juga dapat menambahkan profil penilaian, pemberi saran, atau opsi CORS ke indeks (parameter ini dihilangkan dari sampel agar ringkas). Anda dapat menemukan informasi lebih lanjut tentang objek SearchIndex dan bagian penyusunnya di daftar properti SearchIndex, serta di referensi REST API.

Catatan

Anda selalu dapat membuat daftar objek Field secara langsung alih-alih menggunakan FieldBuilder jika diperlukan. Misalnya, Anda mungkin tidak ingin menggunakan kelas model atau mungkin perlu menggunakan kelas model yang ada yang tidak ingin diubah dengan menambahkan atribut.

Memanggil CreateIndex di Main()

Main membuat indeks "hotel" baru dengan memanggil metode di atas:

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

Menggunakan kelas model untuk representasi data

Sampel DotNetHowTo menggunakan kelas model untuk struktur data Hotel, Address, dan Kamar. Hotel merujuk Address, jenis kompleks tingkat tunggal (bidang multi-bagian), dan Room (kumpulan bidang multi-bagian).

Anda bisa menggunakan jenis ini untuk membuat dan memuat indeks, dan menyusun respons dari kueri:

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

Pendekatan alternatif adalah menambahkan bidang ke indeks secara langsung. Contoh berikut ini hanya memperlihatkan beberapa bidang.

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

Definisi bidang

Model data Anda di .NET dan skema indeks yang sesuai akan mendukung pengalaman pencarian yang ingin Anda berikan kepada pengguna akhir Anda. Setiap objek tingkat atas di .NET, seperti dokumen pencarian dalam indeks pencarian, sesuai dengan hasil pencarian yang akan Anda sajikan di antarmuka pengguna Anda. Misalnya, dalam aplikasi pencarian hotel, pengguna akhir Anda mungkin ingin mencari berdasarkan nama hotel, fitur hotel, atau karakteristik kamar tertentu.

Dalam setiap kelas, bidang ditentukan dengan jenis data dan atribut yang menentukan cara penggunaannya. Nama setiap properti publik di setiap peta kelas ke bidang dengan nama yang sama dalam definisi indeks.

Lihatlah cuplikan berikut yang menarik beberapa definisi bidang dari kelas Hotel. Perhatikan bahwa Alamat dan Kamar adalah jenis C# dengan definisi kelas mereka sendiri (lihat kode sampel jika Anda ingin melihatnya). Keduanya adalah jenis kompleks. Untuk informasi selengkapnya, lihat Cara memodelkan jenis kompleks.

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

Memilih kelas bidang

Saat menentukan bidang, Anda dapat menggunakan kelas SearchField dasar, atau Anda dapat menggunakan model pembantu turunan yang berfungsi sebagai "templat", dengan properti yang telah dikonfigurasi sebelumnya.

Tepat satu bidang dalam indeks Anda harus berfungsi sebagai kunci dokumen (IsKey = true). Ini harus menjadi string, dan harus secara unik mengidentifikasi setiap dokumen. Ini juga diperlukan untuk memiliki IsHidden = true, yang berarti tidak dapat terlihat dalam hasil pencarian.

Jenis bidang Deskripsi dan penggunaan
SearchField Kelas dasar, dengan sebagian besar properti diatur ke null, kecuali Name yang diperlukan, dan AnalyzerName default yang sesuai dengan Lucene standar.
SimpleField Model pembantu. Dapat berupa jenis data apa pun, selalu tidak dapat ditelusuri (diabaikan untuk kueri penelusuran teks lengkap), dan dapat diambil kembali (tidak disembunyikan). Atribut lain tidak aktif secara default, tetapi dapat diaktifkan. Anda mungkin menggunakan SimpleField untuk ID dokumen atau bidang yang hanya digunakan dalam filter, faset, atau profil penilaian. Jika demikian, pastikan untuk menerapkan atribut apa pun yang diperlukan untuk skenario, seperti IsKey = true untuk ID dokumen. Untuk informasi lebih lanjut, lihat SimpleFieldAttribute.cs dalam kode sumber.
SearchableField Model pembantu. Harus berupa string, dan selalu dapat dicari dan diambil. Atribut lain tidak aktif secara default, tetapi dapat diaktifkan. Karena jenis bidang ini dapat dicari, ia mendukung sinonim dan kelengkapan lengkap properti penganalisis. atau informasi lebih lanjut, lihat SearchableFieldAttribute.csdalam kode sumber.

Apakah Anda menggunakan dasar SearchField API atau salah satu model pembantu, Anda harus secara eksplisit mengaktifkan atribut filter, faset, dan sort. Contoh, IsFilterable, IsSortable, and IsFacetable harus secara eksplisit dikaitkan, seperti yang ditunjukkan pada sampel di atas.

Menambahkan atribut bidang

Perhatikan bagaimana setiap bidang dihiasi dengan atribut seperti IsFilterable, IsSortable, IsKey, dan AnalyzerName. Atribut ini memetakan langsung ke atribut bidang yang sesuai dalam indeks Pencarian Azure AI. Kelas FieldBuilder menggunakan properti ini untuk membuat definisi bidang untuk indeks.

Pemetaan jenis data

Jenis .NET dari properti memetakan ke jenis bidang yang setara dalam definisi indeks. Misalnya, properti string Category memetakan ke bidang category, yang berjenis Edm.String. Ada pemetaan jenis yang sama antara bool?, Edm.Boolean, DateTimeOffset?, Edm.DateTimeOffset dan sebagainya.

Apakah Anda kebetulan memperhatikan properti SmokingAllowed?

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

Atribut JsonIgnore pada properti ini memberitahukan kepada pihak FieldBuilder untuk tidak menserialisasikannya ke indeks sebagai bidang. Ini adalah cara yang bagus untuk membuat properti yang dihitung pihak klien yang dapat Anda gunakan sebagai pembantu dalam aplikasi Anda. Dalam hal ini, properti SmokingAllowed mencerminkan apakah ada Room dalam koleksi Rooms yang memperbolehkan merokok. Jika semua salah, itu menunjukkan bahwa seluruh hotel tidak mengizinkan merokok.

Muat indeks

Langkah selanjutnya dalam Main mengisi indeks "hotel" yang baru dibuat. Populasi indeks ini dilakukan dalam metode berikut: (Beberapa kode diganti dengan "..." untuk tujuan ilustrasi. Lihat solusi sampel lengkap untuk kode populasi data lengkap.)

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

Metode ini memiliki empat bagian. Yang pertama membuat array tiga Hotel objek masing-masing dengan tiga Room objek yang akan berfungsi sebagai data input kami untuk diunggah ke indeks. Data ini dikodekan secara permanen untuk kesederhanaan. Dalam aplikasi aktual, data kemungkinan akan berasal dari sumber data eksternal seperti database SQL.

Bagian kedua membuat IndexDocumentsBatch yang berisi dokumen. Anda menentukan operasi yang ingin Anda terapkan ke batch pada saat Anda membuatnya, dalam hal ini dengan memanggil IndexDocumentsAction.Upload. Batch kemudian diunggah ke indeks Pencarian Azure AI dengan IndexDocuments metode .

Catatan

Dalam contoh ini, kami hanya mengunggah dokumen. Jika Anda ingin menggabungkan perubahan ke dalam dokumen yang sudah ada atau menghapus dokumen, Anda bisa membuat batch dengan menelepon IndexDocumentsAction.Merge, IndexDocumentsAction.MergeOrUpload, atau sebagai IndexDocumentsAction.Delete gantinya. Anda juga dapat mencampur operasi yang berbeda dalam satu batch dengan memanggil IndexBatch.New, yang mengambil kumpulan IndexDocumentsAction objek, yang masing-masing memberi tahu Azure AI Search untuk melakukan operasi tertentu pada dokumen. Anda dapat membuat IndexDocumentsAction masing-masing dengan operasinya sendiri dengan memanggil metode yang sesuai seperti IndexDocumentsAction.Merge,IndexAction.Upload, dan sebagainya.

Bagian ketiga dari metode ini adalah blok tangkapan yang menangani kasus kesalahan penting untuk pengindeksan. Jika layanan pencarian Anda gagal mengindeks beberapa dokumen dalam batch, akan RequestFailedException dilemparkan. Pengecualian dapat terjadi jika Anda mengindeks dokumen saat layanan Anda berada di bawah beban berat. Sangat direkomendasikan untuk menangani kasus ini secara eksplisit dengan kode Anda. Anda dapat menunda lalu mencoba mengindeks dokumen yang gagal, atau Anda dapat mencatat dan melanjutkan seperti sampel, atau Anda dapat melakukan hal lain tergantung pada persyaratan konsistensi data aplikasi Anda. Alternatifnya adalah menggunakan SearchIndexingBufferedSender untuk batching cerdas, pembilasan otomatis, dan percobaan ulang untuk tindakan pengindeksan yang gagal. Lihat contoh ini untuk konteks selengkapnya.

Terakhir, metode UploadDocuments akan tertunda selama dua detik. Pengindeksan terjadi secara asinkron di layanan pencarian Anda, sehingga aplikasi contoh perlu menunggu beberapa saat untuk memastikan bahwa dokumen tersedia untuk pencarian. Penundaan seperti ini biasanya hanya diperlukan dalam demo, pengujian, dan aplikasi contoh.

Panggil UploadDocuments di Main()

Cuplikan kode berikut mengatur instans SearchClient menggunakan metode GetSearchClient pada indexClient. IndexClient menggunakan kunci API admin pada permintaannya, yang diperlukan untuk memuat atau merefresh dokumen.

Pendekatan alternatif adalah menelepon SearchClient secara langsung, meneruskan kunci API admin pada AzureKeyCredential.

SearchClient searchClient = indexClient.GetSearchClient(indexName);

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

Jalankan Kueri

Pertama, siapkan SearchClient yang membaca titik akhir layanan dan kunci API kueri dari 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;
}

Kedua, tentukan metode yang mengirim permintaan kueri.

Setiap kali metode menjalankan kueri, ia membuat objek SearchOptions baru. Obyek ini digunakan untuk menentukan opsi tambahan untuk kueri seperti pengurutan, pemfilteran, penomoran halaman, dan faseting. Dalam metode ini, kami mengatur properti Filter, Select, dan OrderBy untuk kueri yang berbeda. Untuk informasi selengkapnya tentang sintaks ekspresi kueri pencarian, Sintaks kueri sederhana.

Langkah selanjutnya adalah eksekusi kueri. Menjalankan pencarian dilakukan menggunakan metode SearchClient.Search. Untuk setiap kueri, teruskan teks pencarian untuk digunakan sebagai string (atau "*" jika tidak ada teks pencarian), ditambah opsi pencarian yang dibuat sebelumnya. Kami juga menentukan Hotel sebagai parameter jenis untukSearchClient.Search, yang memberitahu SDK untuk mendeserialisasi dokumen dalam hasil pencarian menjadi objek jenis 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);
}

Ketiga, tentukan metode yang menulis respons, mencetak setiap dokumen ke konsol:

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

    Console.WriteLine();
}

Memanggil RunQueries di Main()

SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

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

Menjelajahi konstruksi kueri

Mari kita lihat lebih dekat pada setiap kuerinya secara bergantian. Berikut adalah kode untuk menjalankan kueri pertama:

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

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

WriteDocuments(results);

Dalam hal ini, kami sedang mencari seluruh indeks untuk kata "motel" di bidang yang dapat dicari dan kami hanya ingin mengambil nama hotel, seperti yang ditentukan oleh opsi Select. Berikut hasilnya:

Name: Secret Point Motel

Name: Twin Dome Motel

Di kueri kedua, gunakan filter untuk memilih kamar dengan tarif per malam kurang dari $ 100. Kembalikan hanya ID hotel dan deskripsi dalam hasil:

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

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

Kueri di atas menggunakan ekspresi OData $filter, Rooms/any(r: r/BaseRate lt 100), untuk memfilter dokumen dalam indeks. Ini menggunakan operator apa pun untuk menerapkan 'BaseRate lt 100' ke setiap item dalam koleksi Kamar. Untuk informasi selengkapnya, lihat sintaks filter OData.

Dalam kueri ketiga, temukan dua hotel teratas yang baru saja direnovasi, dan tampilkan nama hotel dan tanggal renovasi terakhir. Berikut kodenya:

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

Dalam kueri terakhir, temukan semua nama hotel yang cocok dengan kata "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);

Bagian ini menyimpulkan pengenalan ini ke .NET SDK, tetapi jangan berhenti di sini. Bagian berikutnya menyarankan sumber daya lain untuk mempelajari selengkapnya tentang pemrograman dengan Azure AI Search.

Langkah berikutnya