如何在 C# .NET 應用程式中使用 Azure.Search.Documents

本文說明如何使用 C# 和 Azure.Search.Documents (11 版) 用戶端程式庫來建立和管理搜尋物件。

關於第 11 版

適用于 .NET 的 Azure SDK 包含來自 Azure SDK 小組的 Azure.Search.Documents 用戶端程式庫,其功能相當於先前的用戶端程式庫 Microsoft.Azure.Search。 版本 11 在 Azure 可程式設計方面更為一致。 某些範例包括 AzureKeyCredential 金鑰驗證,以及 JSON 序列化的 System.Text.Json.Serialization

如同舊版,您可以使用此程式庫來:

  • 建立和管理搜尋索引、資料來源、索引子、技能集和同義字對應
  • 載入和管理索引中的搜尋檔
  • 執行查詢,完全不需要處理 HTTP 和 JSON 的詳細資料
  • 叫用和管理 AI 擴充 (技能集) 和輸出

程式庫會以單一 Azure.Search.Documents NuGet 套件的形式散發,其中包含用來以程式設計方式存取搜尋服務的所有 API。

用戶端程式庫會定義類別,例如 SearchIndexSearchFieldSearchDocument,以及定義作業,例如 SearchIndexClientSearchClient 類別上的 SearchIndexClient.CreateIndexSearchClient.Search。 這些類別可編成以下命名空間:

Azure.Search.Documents (11 版) Azure 認知搜尋 REST API 的目標版本 2020-06-30

用戶端程式庫不提供 服務管理作業,例如建立和調整搜尋服務及管理 API 金鑰。 如果您需要從 .NET 應用程式管理搜尋資源,請使用適用于 .NET 的 Azure SDK 中的 Microsoft.Azure.Management.Search 程式庫。

升級至 v11

如果您已使用舊版 .NET SDK,而且想要升級至目前正式推出的版本,請參閱 升級至 Azure 認知搜尋 .NET SDK 第 11 版

SDK 需求

  • Visual Studio 2019 或更新版本。

  • 您自己的 Azure 認知搜尋服務。 為了使用 SDK,您需要為服務命名,還需要一或多個 API 金鑰。 如果您沒有服務,請在入口網站中建立服務

  • 使用>工具 NuGet 套件管理員> 在 Visual Studio 中管理方案的 NuGet 套件,下載Azure.Search.Documents套件。 搜尋套件名稱 Azure.Search.Documents

適用於 .NET 的 Azure SDK 符合 .NET Standard 2.0,這表示最低需求為 .NET Framework 4.6.1 和 .NET Core 2.0。

範例應用程式

本文「依範例教導」,依賴 GitHub 上的 DotNetHowTo 程式碼範例來說明 Azure 認知搜尋的基本概念,特別是如何建立、載入和查詢搜尋索引。

針對本文的其餘部分,假設有一個名為 「hotels」 的新索引,其中填入了一些檔,其中包含數個符合結果的查詢。

以下是主要程式,其中顯示整體流程:

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

接下來是輸出的部分螢幕擷取畫面,假設您使用有效的服務名稱和 API 金鑰來執行此應用程式:

Console.WriteLine output from the sample program

用戶端類型

用戶端程式庫會針對各種作業使用三種用戶端類型: SearchIndexClient 建立、更新或刪除索引、 SearchClient 載入或查詢索引,以及 SearchIndexerClient 使用索引子和技能集。 本文著重于前兩個。

所有用戶端至少都需要服務名稱或端點,以及 API 金鑰。 通常會在組態檔中提供這項資訊,類似于您在 DotNetHowTo 範例應用程式中找到 appsettings.json 的內容。 若要從組態檔讀取,請將 新增 using Microsoft.Extensions.Configuration; 至您的程式。

下列語句會建立用來建立、更新或刪除索引的索引用戶端。 它會取得搜尋端點和系統管理 API 金鑰。

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

下一個語句會建立用來載入檔或執行查詢的搜尋用戶端。 SearchClient 需要索引。 您需要系統管理員 API 金鑰才能載入檔,但您可以使用查詢 API 金鑰來執行查詢。

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

注意

例如,如果您為匯入作業提供不正確金鑰 (,需要系統管理員金鑰的查詢金鑰) ,則會 SearchClient 在第一次呼叫作業方法時擲回 CloudException 錯誤訊息「禁止」。 如果發生這種情況,請仔細檢查 API 金鑰。

刪除索引

在開發初期階段,您可能會想要包含 DeleteIndex 語句來刪除進行中的工作索引,以便您可以使用更新的定義重新建立它。 Azure 認知搜尋的範例程式碼通常包含刪除步驟,以便您可以重新執行範例。

下列程式程式碼會呼叫 DeleteIndexIfExists

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

這個方法會使用指定的 SearchIndexClient 來檢查索引是否存在,如果是,則會刪除它:

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

注意

本文中的範例程式碼會使用同步方法來簡化,但您應該在自己的應用程式中使用非同步方法,讓它們保持可調整且回應。 例如,在上述方法中,您可以使用 DeleteIndexAsync ,而不是 DeleteIndex

建立索引

您可以使用 SearchIndexClient 來建立索引。

下列方法會建立新的 SearchIndex 物件,其中包含定義新索引架構的物件清單 SearchField 。 每個欄位均有一個名稱、資料類型和一些屬性,以用於定義欄位的搜尋行為。

您可以使用 從模型類別 FieldBuilder 定義欄位。 FieldBuilder 類別會檢查指定 Hotel 模型類別的公用屬性 (property) 和屬性 (attribute),進而使用反映來建立索引的 SearchField 物件清單。 我們稍後會仔細查看 Hotel 類別。

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

除了欄位之外,您也可以將評分設定檔、建議程式或 CORS 選項新增至索引, (這些參數會從範例中省略,以求簡潔) 。 您可以在屬性清單中,以及REST API 參考中找到 SearchIndex 物件及其組成部分 SearchIndex 的詳細資訊。

注意

如有需要,您永遠可以直接建立 Field 物件清單,而不是使用FieldBuilder。 例如,您可能不想使用模型類別,或您可能需要使用不想藉由新增屬性來修改的現有模型類別。

在 Main 中呼叫 CreateIndex ()

Main 藉由呼叫上述方法來建立新的 「hotels」 索引:

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

使用模型類別進行資料表示

DotNetHowTo 範例會針對 HotelAddressRoom 資料結構使用模型類別。 Hotel 參考 Address 、單一層級複雜類型 (多部分欄位) ,以及 Room (多部分欄位集合) 。

您可以使用這些類型來建立和載入索引,以及建構來自查詢的回應:

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

替代方法是直接將欄位新增至索引。 下列範例只顯示幾個欄位。

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

欄位定義

.NET 中的資料模型及其對應的索引架構應該支援您想要提供給使用者的搜尋體驗。 .NET 中的每個最上層物件,例如搜尋索引中的搜尋檔,會對應至您在使用者介面中出現的搜尋結果。 例如,在旅館搜尋應用程式中,使用者可能會想要依旅館名稱、旅館的功能或特定房間的特性進行搜尋。

在每個類別中,欄位會以資料類型和屬性定義,以決定其使用方式。 每個類別中每個公用屬性的名稱都會對應至索引定義中具有相同名稱的欄位。

請查看下列程式碼片段,從 Hotel 類別提取數個欄位定義。 請注意,如果想要檢視範例程式碼,位址和會議室是具有其本身類別定義的 C# 類型, (參考範例) 程式碼。 兩者都是複雜類型。 如需詳細資訊,請參閱 如何建立複雜類型的模型

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

選擇欄位類別

定義欄位時,您可以使用基 SearchField 類,或使用衍生協助程式模型做為「範本」,並具有預先設定的屬性。

索引中的一個欄位必須做為檔索引鍵 (IsKey = true) 。 它必須是字串,而且必須唯一識別每個檔。 也需要有 IsHidden = true ,這表示無法在搜尋結果中顯示。

欄位類型 描述和使用方式
SearchField 基類,其中大部分屬性都設定為 null,但除了 Name 必要屬性之外,預設 AnalyzerName 為標準 Lucene。
SimpleField 協助程式模型。 可以是任何資料類型,一律為不可搜尋 (全文檢索搜尋查詢) 忽略,而且無法擷取 (它不會隱藏) 。 其他屬性預設為關閉,但可以啟用。 您可以針對僅用於篩選、Facet 或評分設定檔的文件識別碼或欄位使用 SimpleField。 若是如此,請務必套用案例所需的任何屬性,例如文件識別碼的 IsKey = true。 如需詳細資訊,請參閱原始程式碼中的 SimpleFieldAttribute.cs
SearchableField 協助程式模型。 必須是字串,而且一律可搜尋且可擷取。 其他屬性預設為關閉,但可以啟用。 因為此欄位類型是可搜尋,所以其支援同義字和分析器屬性的完整補語。 如需詳細資訊,請參閱原始程式碼中的 SearchableFieldAttribute.cs

無論您使用的是基本 SearchField API 或其中一個 協助程式模型,都必須明確啟用篩選、Facet 和排序屬性。 例如,IsFilterableIsSortableIsFacetable 必須明確屬性化,如上述範例所示。

新增欄位屬性

請注意,每個欄位如何以 、 IsSortableIsKeyAnalyzerNameIsFilterable 屬性裝飾。 這些屬性會直接對應至 Azure 認知搜尋索引中的對應欄位屬性。 類別 FieldBuilder 會使用這些屬性來建構索引的欄位定義。

欄位類型對應

屬性的 .NET 類型會對應至索引定義中的對等欄位類型。 例如,Category 字串屬性會對應至 category 欄位 (此欄位屬於 Edm.String 類型)。 、 Edm.BooleanDateTimeOffset?Edm.DateTimeOffset 等之間 bool? 有類似的類型對應。

您是否注意到 SmokingAllowed 屬性?

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

JsonIgnore這個屬性上的 屬性會告訴 FieldBuilder ,不要將它序列化為欄位的索引。 這是建立用戶端匯出屬性的絕佳方式,您可以在應用程式中當做協助程式使用。 在此情況下, SmokingAllowed 屬性會反映集合中 Rooms 是否有任何 Room 允許抽氣。 如果全都為 false,則表示整個旅館不允許抽氣。

載入索引

中的下一個步驟 Main 會填入新建立的 「hotels」 索引。 此索引母體擴展是在下列方法中完成: (某些程式碼取代為 「...」用於圖例用途。請參閱完整資料母體擴展程式碼的完整範例解決方案。)

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

此方法分四個部分。 第一個會建立 3 個物件的陣列,每個物件有 3 HotelRoom 個物件,作為要上傳至索引的輸入資料。 為簡單起見,此資料採硬式編碼。 在實際應用程式中,資料可能來自外部資料源,例如 SQL 資料庫。

第二個部分會建立包含文件的 IndexDocumentsBatch 。 您在建立批次時 (在此案例中,是藉由呼叫 IndexDocumentsAction.Upload),指定要套用至該批次的作業。 然後,批次會透過 IndexDocuments 方法上傳至 Azure 認知搜尋索引。

注意

在此範例中,我們只上傳文件。 如果您想要將變更合併至現有的文件,或是刪除文件,您可以改為呼叫 IndexDocumentsAction.MergeIndexDocumentsAction.MergeOrUploadIndexDocumentsAction.Delete 來建立批次。 您也可以藉由呼叫 IndexBatch.New 來混合單一批次中的不同作業,其會採用 物件的集合 IndexDocumentsAction ,每個物件都會告訴 Azure 認知搜尋在檔上執行特定作業。 您可以建立每個擁有自己作業的 IndexDocumentsAction,方法是呼叫對應的方法,例如 IndexDocumentsAction.MergeIndexAction.Upload 等等。

此方法的第三部分是擷取區塊,該區塊會為編制索引處理重要錯誤情況。 如果您的搜尋服務無法為批次中的部分檔編制索引, RequestFailedException 則會擲回 。 如果您在服務負載過重時編制檔索引,就會發生例外狀況。 我們強烈建議您在程式碼中明確處理此情況。 您可以延遲,然後重新嘗試將失敗的文件編制索引,或像範例一樣加以記錄並繼續,或是根據您應用程式的資料一致性需求執行其他操作。 替代方式是使用 SearchIndexingBufferedSender 進行智慧型批次處理、自動排清,以及重試失敗的索引編制動作。 如需更多內容,請參閱 此範例

最後,UploadDocuments 方法會延遲兩秒。 索引會在您的搜尋服務中以非同步方式進行,因此範例應用程式必須等候一段時間,以確保檔可供搜尋。 通常只有在示範、測試和範例應用程式中,才需要這類延遲。

在 Main 中呼叫 UploadDocuments ()

下列程式碼片段會使用 GetSearchClient indexClient 的 方法來設定 的實例 SearchClient 。 indexClient 會在其要求上使用系統管理員 API 金鑰,這是載入或重新整理檔的必要專案。

替代方法是直接呼叫 SearchClient ,在 上 AzureKeyCredential 傳入管理 API 金鑰。

SearchClient searchClient = indexClient.GetSearchClient(indexName);

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

執行查詢

首先,設定 , SearchClientappsettings.json讀取搜尋端點和查詢 API 金鑰:

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

其次,定義傳送查詢要求的方法。

每次方法執行查詢時,都會建立新的 SearchOptions 物件。 這個物件可用來指定查詢的其他選項,例如排序、篩選、分頁和 Facet。 在此方法中,我們會為不同的查詢設定 FilterSelectOrderBy 屬性。 如需搜尋查詢運算式語法的詳細資訊, 請參閱簡單查詢語法

下一步是實際執行搜尋查詢, 執行搜尋是使用 SearchClient.Search 方法完成的。 針對每個查詢,傳遞搜尋文字作為字串 (,或者 "*" 如果沒有搜尋文字) ,再加上稍早建立的搜尋選項。 我們也指定了 Hotel 做為 SearchClient.Search 的類型參數,藉此告訴 SDK 將搜尋結果中的文件還原序列化為 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" is not supported yet when deserialize 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);
}

第三,定義方法以寫入回應,將每份檔列印到主控台:

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

    Console.WriteLine();
}

在 Main 中呼叫 RunQueries ()

SearchClient indexClientForQueries = CreateSearchClientForQueries(indexName, configuration);

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

探索查詢建構

讓我們依序仔細查看每個查詢。 以下是執行第一個查詢的程式碼︰

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

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

WriteDocuments(results);

在此情況下,我們會在任何可搜尋的欄位中搜尋 「hotel」 一詞的整個索引,而我們只想要擷取旅館名稱,如 選項所 Select 指定。 以下是結果:

Name: Secret Point Motel

Name: Twin Dome Motel

在第二個查詢中,使用篩選來選取夜間速率小於 $100 的會議室。 只傳回結果中的旅館識別碼和描述:

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

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

上述查詢會使用 OData $filter 運算式 Rooms/any(r: r/BaseRate lt 100) 來篩選索引中的檔。 這會使用 任何運算子 ,將 'BaseRate lt 100' 套用至 Rooms 集合中的每個專案。 如需詳細資訊,請參閱 OData 篩選語法

在第三個查詢中,尋找最近一次重新整理的前兩家旅館,並顯示旅館名稱和最後一個活頁日期。 程式碼如下:

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

在最後一個查詢中,尋找符合 「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);

本節將結束此 .NET SDK 簡介,但不在此停止。 下一節會建議其他資源,以深入瞭解使用 Azure 認知搜尋進行程式設計。

後續步驟