快速入门:使用 Azure.Search.Documents 客户端库创建搜索索引Quickstart: Create a search index using the Azure.Search.Documents client library

使用新的 Azure.Search.Documents(版本 11)客户端库以 C# 创建 .NET Core 控制台应用程序,用于创建、加载和查询搜索索引。Use the new Azure.Search.Documents (version 11) client library to create a .NET Core console application in C# that creates, loads, and queries a search index.

可以下载源代码,从一个已完成的项目着手,或按照本文中的步骤操作,创建自己的项目。You can download the source code to start with a finished project or follow the steps in this article to create your own.

备注

正在查找早期版本?Looking for an earlier version? 请转而参阅使用 Microsoft.Azure.Search v10 创建搜索索引See Create a search index using Microsoft.Azure.Search v10 instead.

先决条件Prerequisites

开始之前,需具备以下工具和服务:Before you begin, have the following tools and services:

设置项目时,将下载 Azure.Search.Documents NuGet 包When setting up your project, you will download the Azure.Search.Documents NuGet package.

用于 .NET 的 Azure SDK 符合 .NET Standard 2.0,这意味着 .NET Framework 4.6.1 和 .NET Core 2.0 是最低要求。Azure SDK for .NET conforms to .NET Standard 2.0, which means .NET Framework 4.6.1 and .NET Core 2.0 as minimum requirements.

设置项目Set up your project

汇总服务连接信息,然后启动 Visual Studio 以新建可在 .NET Core 上运行的控制台应用项目。Assemble service connection information, and then start Visual Studio to create a new Console App project that can run on .NET Core.

复制密钥和终结点Copy a key and endpoint

对服务的调用要求每个请求都有一个 URL 终结点和一个访问密钥。Calls to the service require a URL endpoint and an access key on every request. 第一步,找到要添加到项目中的 API 密钥和 URL。As a first step, find the API key and URL to add to your project. 在稍后的步骤中创建客户端时,将指定这两个值。You will specify both values when creating the client in a later step.

  1. 登录到 Azure 门户,在搜索服务的“概述”页中获取 URL。Sign in to the Azure portal, and in your search service Overview page, get the URL. 示例终结点可能类似于 https://mydemo.search.azure.cnAn example endpoint might look like https://mydemo.search.azure.cn.

  2. 在“设置” > “密钥”中,获取管理员密钥以获得针对服务的完全权限,需要该密钥才可创建或删除对象 。In Settings > Keys, get an admin key for full rights on the service, required if you are creating or deleting objects. 有两个可互换的主要密钥和辅助密钥。There are two interchangeable primary and secondary keys. 可以使用其中任意一个。You can use either one.

    获取 HTTP 终结点和访问密钥Get an HTTP endpoint and access key

所有请求对发送到服务的每个请求都需要 API 密钥。All requests require an api-key on every request sent to your service. 具有有效的密钥可以在发送请求的应用程序与处理请求的服务之间建立信任关系,这种信任关系以每个请求为基础。Having a valid key establishes trust, on a per request basis, between the application sending the request and the service that handles it.

安装 NuGet 包Install the NuGet package

项目创建后,添加客户端库。After the project is created, add the client library. Azure.Search.Documents 包包含一个客户端库,其中提供了用于与 .NET 中的搜索服务一起使用的所有 API。The Azure.Search.Documents package consists of one client library that provides all of the APIs used to work with a search service in .NET.

  1. 启动 Visual Studio 并创建 .NET Core 控制台应用程序。Start Visual Studio and create a .NET Core console application.

  2. 在“工具” > “NuGet 包管理器”中,选择“管理解决方案的 NuGet 包...” 。In Tools > NuGet Package Manager, select Manage NuGet Packages for Solution....

  3. 单击“浏览”。Click Browse.

  4. 搜索 Azure.Search.Documents,并选择 11.0 或更高版本。Search for Azure.Search.Documents and select version 11.0 or later.

  5. 单击右侧的“安装”,将该程序集添加到你的项目和解决方案。Click Install on the right to add the assembly to your project and solution.

创建搜索客户端Create a search client

  1. 在“Program.cs”中,将命名空间更改为 AzureSearch.SDK.Quickstart.v11,然后添加以下 using 指令。In Program.cs, change the namespace to AzureSearch.SDK.Quickstart.v11 and then add the following using directives.

    using Azure;
    using Azure.Search.Documents;
    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    using Azure.Search.Documents.Models;
    
  2. 创建两个客户端:SearchIndexClient 创建索引,SearchClient 加载并查询现有索引。Create two clients: SearchIndexClient creates the index, and SearchClient loads and queries an existing index. 两者都需要服务终结点和管理员 API 密钥才能使用创建/删除权限进行身份验证。Both need the service endpoint and an admin API key for authentication with create/delete rights.

    static void Main(string[] args)
    {
        string serviceName = "<YOUR-SERVICE-NAME>";
        string indexName = "hotels-quickstart";
        string apiKey = "<YOUR-ADMIN-API-KEY>";
    
         // Create a SearchIndexClient to send create/delete index commands
        Uri serviceEndpoint = new Uri($"https://{serviceName}.search.azure.cn/");
         AzureKeyCredential credential = new AzureKeyCredential(apiKey);
         SearchIndexClient adminClient = new SearchIndexClient(serviceEndpoint, credential);
    
         // Create a SearchClient to load and query documents
         SearchClient srchclient = new SearchClient(serviceEndpoint, indexName, credential);
    

1 - 创建索引1 - Create an index

本快速入门生成 Hotels 索引,你将在其中加载酒店数据并对其执行查询。This quickstart builds a Hotels index that you'll load with hotel data and execute queries against. 在此步骤中,定义索引中的字段。In this step, define the fields in the index. 每个字段定义都包含名称、数据类型以及确定如何使用该字段的属性。Each field definition includes a name, data type, and attributes that determine how the field is used.

在此示例中,为了简单和可读性,使用了 Azure.Search.Documents 库的同步方法。In this example, synchronous methods of the Azure.Search.Documents library are used for simplicity and readability. 但是,对于生产场景,应使用异步方法来保持应用程序的可缩放性和响应性。However, for production scenarios, you should use asynchronous methods to keep your app scalable and responsive. 例如,使用 CreateIndexAsync,而不是 CreateIndexFor example, you would use CreateIndexAsync instead of CreateIndex.

  1. 向项目添加一个空的类定义:Hotel.csAdd an empty class definition to your project: Hotel.cs

  2. 将以下代码复制到 Hotel.cs 以定义酒店文档的结构。Copy the following code into Hotel.cs to define the structure of a hotel document. 该字段的特性决定字段在应用程序中的使用方式。Attributes on the field determine how it is used in an application. 例如,IsFilterable 属性必须分配给每个支持筛选表达式的字段。For example, the IsFilterable attribute must be assigned to every field that supports a filter expression.

    using System;
    using System.Text.Json.Serialization;
    using Azure.Search.Documents.Indexes;
    using Azure.Search.Documents.Indexes.Models;
    
    namespace AzureSearch.Quickstart
    {
        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(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)]
            [JsonPropertyName("Description_fr")]
            public string DescriptionFr { get; set; }
    
            [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public string Category { get; set; }
    
            [SearchableField(IsFilterable = true, IsFacetable = true)]
            public string[] Tags { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public bool? ParkingIncluded { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public DateTimeOffset? LastRenovationDate { get; set; }
    
            [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
            public double? Rating { get; set; }
    
            [SearchableField]
            public Address Address { get; set; }
        }
    }
    

    在 Azure.Search.Documents 客户端库中,可以使用 SearchableFieldSimpleField 来简化字段定义。In the Azure.Search.Documents client library, you can use SearchableField and SimpleField to streamline field definitions. 两者都是 SearchField 的派生形式,可能会简化你的代码:Both are derivatives of a SearchField and can potentially simplify your code:

    • SimpleField 可以是任何数据类型,始终不可搜索(全文搜索查询将忽略它),并且可检索(未隐藏)。SimpleField can be any data type, is always non-searchable (it's ignored for full text search queries), and is retrievable (it's not hidden). 其他属性默认情况下处于关闭状态,但可以启用。Other attributes are off by default, but can be enabled. 你可能会将 SimpleField 用于仅在筛选器、facet 或计分概要文件中使用的文档 ID 或字段。You might use a SimpleField for document IDs or fields used only in filters, facets, or scoring profiles. 如果是这样,请确保应用该方案所需的所有属性,例如为文档 ID 应用 IsKey = trueIf so, be sure to apply any attributes that are necessary for the scenario, such as IsKey = true for a document ID. 有关详细信息,请参阅源代码中的 SimpleFieldAttribute.csFor more information, see SimpleFieldAttribute.cs in source code.

    • SearchableField 必须是字符串,并且始终可搜索、可检索。SearchableField must be a string, and is always searchable and retrievable. 其他属性默认情况下处于关闭状态,但可以启用。Other attributes are off by default, but can be enabled. 因为此字段类型是可搜索的,所以它支持同义词和分析器属性的完整补集。Because this field type is searchable, it supports synonyms and the full complement of analyzer properties. 有关详细信息,请参阅源代码中的 SearchableFieldAttribute.csFor more information, see the SearchableFieldAttribute.cs in source code.

    无论使用基本 SearchField API 还是任一帮助程序模型,都必须显式启用筛选器、facet 和排序属性。Whether you use the basic SearchField API or either one of the helper models, you must explicitly enable filter, facet, and sort attributes. 例如,IsFilterableIsSortableIsFacetable 必须进行显式属性化,如上例中所示。For example, IsFilterable, IsSortable, and IsFacetable must be explicitly attributed, as shown in the sample above.

  3. 向项目添加第二个空的类定义:Address.cs。Add a second empty class definition to your project: Address.cs. 将以下代码复制到类中。Copy the following code into the class.

    using Azure.Search.Documents.Indexes;
    
     namespace AzureSearch.Quickstart
     {
         public partial class Address
         {
             [SearchableField(IsFilterable = true)]
             public string StreetAddress { get; set; }
    
             [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
             public string City { get; set; }
    
             [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
             public string StateProvince { get; set; }
    
             [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
             public string PostalCode { get; set; }
    
             [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)]
             public string Country { get; set; }
         }
     }
    
  4. 再创建两个类:ToString() 的 Hotel.Methods.cs 和 Address.Methods.cs 将重写 。Create two more classes: Hotel.Methods.cs and Address.Methods.cs for ToString() overrides. 这些类用于在控制台输出中呈现搜索结果。These classes are used to render search results in the console output. 本文未提供这些类的内容,但可以从 GitHub 中的文件里复制代码。The contents of these classes are not provided in this article, but you can copy the code from files in GitHub.

  5. 在 Program.cs 中,创建一个 SearchIndex 对象,然后调用 CreateIndex 方法来表示搜索服务中的索引。In Program.cs, create a SearchIndex object, and then call the CreateIndex method to express the index in your search service. 此索引还包括一个 SearchSuggester 以便在指定字段上启用自动完成。The index also includes a SearchSuggester to enable autocomplete on the specified fields.

     // Create hotels-quickstart index
     private static void CreateIndex(string indexName, SearchIndexClient adminClient)
     {
         FieldBuilder fieldBuilder = new FieldBuilder();
         var searchFields = fieldBuilder.Build(typeof(Hotel));
    
         var definition = new SearchIndex(indexName, searchFields);
    
         var suggester = new SearchSuggester("sg", new[] { "HotelName", "Category", "Address/City", "Address/StateProvince" });
         definition.Suggesters.Add(suggester);
    
         adminClient.CreateOrUpdateIndex(definition);
     }
    

2 - 加载文档2 - Load documents

Azure 认知搜索对存储在服务中的内容进行搜索。Azure Cognitive Search searches over content stored in the service. 在此步骤中,加载符合刚刚创建的酒店索引的 JSON 文档。In this step, you'll load JSON documents that conform to the hotel index you just created.

在 Azure 认知搜索中,搜索文档这一数据结构既是索引输入,也是查询输出。In Azure Cognitive Search, search documents are data structures that are both inputs to indexing and outputs from queries. 文档输入从外部数据源获取,可能是数据库中的行、Blob 存储中的 blob 或磁盘上的 JSON 文档。As obtained from an external data source, document inputs might be rows in a database, blobs in Blob storage, or JSON documents on disk. 在此示例中,我们采用了快捷方式,并在代码本身中嵌入了四个酒店的 JSON 文档。In this example, we're taking a shortcut and embedding JSON documents for four hotels in the code itself.

上传文档时,必须使用 IndexDocumentsBatch 对象。When uploading documents, you must use an IndexDocumentsBatch object. IndexDocumentsBatch 对象包含操作集合,其中每个操作均包含一个文档和一个属性,该属性用于指示 Azure 认知搜索要执行什么操作(upload、merge、delete 和 mergeOrUpload)。An IndexDocumentsBatch object contains a collection of Actions, each of which contains a document and a property telling Azure Cognitive Search what action to perform (upload, merge, delete, and mergeOrUpload).

  1. 在 Program.cs 中,创建文档和索引操作的数组,然后将该数组传递给 IndexDocumentsBatchIn Program.cs, create an array of documents and index actions, and then pass the array to IndexDocumentsBatch. 以下文档符合 hotel 类定义的 hotels-quickstart 索引。The documents below conform to the hotels-quickstart index, as defined by the hotel class.

    // Upload documents in a single Upload request.
    private static void UploadDocuments(SearchClient searchClient)
    {
        IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create(
            IndexDocumentsAction.Upload(
                new Hotel()
                {
                    HotelId = "1",
                    HotelName = "Secret Point Motel",
                    Description = "The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.",
                    DescriptionFr = "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.",
                    Category = "Boutique",
                    Tags = new[] { "pool", "air conditioning", "concierge" },
                    ParkingIncluded = false,
                    LastRenovationDate = new DateTimeOffset(1970, 1, 18, 0, 0, 0, TimeSpan.Zero),
                    Rating = 3.6,
                    Address = new Address()
                    {
                        StreetAddress = "677 5th Ave",
                        City = "New York",
                        StateProvince = "NY",
                        PostalCode = "10022",
                        Country = "USA"
                    }
                }),
            IndexDocumentsAction.Upload(
                new Hotel()
                {
                    HotelId = "2",
                    HotelName = "Twin Dome Motel",
                    Description = "The hotel is situated in a  nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.",
                    DescriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.",
                    Category = "Boutique",
                    Tags = new[] { "pool", "free wifi", "concierge" },
                    ParkingIncluded = false,
                    LastRenovationDate = new DateTimeOffset(1979, 2, 18, 0, 0, 0, TimeSpan.Zero),
                    Rating = 3.60,
                    Address = new Address()
                    {
                        StreetAddress = "140 University Town Center Dr",
                        City = "Sarasota",
                        StateProvince = "FL",
                        PostalCode = "34243",
                        Country = "USA"
                    }
                }),
            IndexDocumentsAction.Upload(
                new Hotel()
                {
                    HotelId = "3",
                    HotelName = "Triple Landscape Hotel",
                    Description = "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services.",
                    DescriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.",
                    Category = "Resort and Spa",
                    Tags = new[] { "air conditioning", "bar", "continental breakfast" },
                    ParkingIncluded = true,
                    LastRenovationDate = new DateTimeOffset(2015, 9, 20, 0, 0, 0, TimeSpan.Zero),
                    Rating = 4.80,
                    Address = new Address()
                    {
                        StreetAddress = "3393 Peachtree Rd",
                        City = "Atlanta",
                        StateProvince = "GA",
                        PostalCode = "30326",
                        Country = "USA"
                    }
                }),
            IndexDocumentsAction.Upload(
                new Hotel()
                {
                    HotelId = "4",
                    HotelName = "Sublime Cliff Hotel",
                    Description = "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.",
                    DescriptionFr = "Le sublime Cliff Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.",
                    Category = "Boutique",
                    Tags = new[] { "concierge", "view", "24-hour front desk service" },
                    ParkingIncluded = true,
                    LastRenovationDate = new DateTimeOffset(1960, 2, 06, 0, 0, 0, TimeSpan.Zero),
                    Rating = 4.60,
                    Address = new Address()
                    {
                        StreetAddress = "7400 San Pedro Ave",
                        City = "San Antonio",
                        StateProvince = "TX",
                        PostalCode = "78216",
                        Country = "USA"
                    }
                })
            );
    
        try
        {
            IndexDocumentsResult result = searchClient.IndexDocuments(batch);
        }
        catch (Exception)
        {
            // If for some reason any documents are dropped during indexing, you can compensate by delaying and
            // retrying. This simple demo just logs the failed document keys and continues.
            Console.WriteLine("Failed to index some of the documents: {0}");
        }
    }
    

    初始化 IndexDocumentsBatch 对象后,可以通过对 SearchClient 对象调用 IndexDocuments 将其发送到索引。Once you initialize the IndexDocumentsBatch object, you can send it to the index by calling IndexDocuments on your SearchClient object.

  2. 将以下代码行添加到 Main()。Add the following lines to Main(). 加载文档是使用 SearchClient 完成的,但此操作还需要对服务的管理员权限,通常与 SearchIndexClient 相关联。Loading documents is done using SearchClient, but the operation also requires admin rights on the service, which is typically associated with SearchIndexClient. 设置此操作的一种方法是通过 SearchIndexClient (在本示例中为 adminClient)获取 SearchClient。One way to set up this operation is to get SearchClient through SearchIndexClient (adminClient in this example).

     SearchClient ingesterClient = adminClient.GetSearchClient(indexName);
    
     // Load documents
     Console.WriteLine("{0}", "Uploading documents...\n");
     UploadDocuments(ingesterClient);
    
  3. 由于这是一个按顺序运行所有命令的控制台应用,因此请在索引和查询之间添加 2 秒的等待时间。Because this is a console app that runs all commands sequentially, add a 2-second wait time between indexing and queries.

    // Wait 2 seconds for indexing to complete before starting queries (for demo and console-app purposes only)
    Console.WriteLine("Waiting for indexing...\n");
    System.Threading.Thread.Sleep(2000);
    

    2 秒的延迟可对索引编制进行补偿(这是异步操作),这样可在执行查询之前对所有文档编制索引。The 2-second delay compensates for indexing, which is asynchronous, so that all documents can be indexed before the queries are executed. 以延迟方式编写代码通常仅在演示、测试和示例应用程序中是必要的。Coding in a delay is typically only necessary in demos, tests, and sample applications.

3 - 搜索索引3 - Search an index

对第一个文档编制索引后,可立即获取查询结果,但索引的实际测试应等到对所有文档编制索引后进行。You can get query results as soon as the first document is indexed, but actual testing of your index should wait until all documents are indexed.

此部分添加了两个功能:查询逻辑和结果。This section adds two pieces of functionality: query logic, and results. 对于查询,请使用 Search 方法。For queries, use the Search method. 此方法采用搜索文本(查询字符串)以及其他选项This method takes search text (the query string) as well as other options.

SearchResults 类表示结果。The SearchResults class represents the results.

  1. 在 Program.cs 中,创建 WriteDocuments 方法,该方法用于将搜索结果输出到控制台 。In Program.cs, create a WriteDocuments method that prints search results to the console.

    // Write search results to console
    private static void WriteDocuments(SearchResults<Hotel> searchResults)
    {
        foreach (SearchResult<Hotel> result in searchResults.GetResults())
        {
            Console.WriteLine(result.Document);
        }
    
        Console.WriteLine();
    }
    
  2. 创建 RunQueries 方法,该方法用于执行查询并返回结果。Create a RunQueries method to execute queries and return results. 结果是 Hotel 对象。Results are Hotel objects. 此示例显示了方法签名和第一个查询。This sample shows the method signature and the first query. 此查询演示了 Select 参数,通过该参数可以使用文档中的选定字段来编写结果。This query demonstrates the Select parameter that lets you compose the result using selected fields from the document.

    // Run queries, use WriteDocuments to print output
    private static void RunQueries(SearchClient srchclient)
    {
        SearchOptions options;
        SearchResults<Hotel> response;
    
        Console.WriteLine("Query #1: Search on empty term '*' to return all documents, showing a subset of fields...\n");
    
        options = new SearchOptions()
        {
            IncludeTotalCount = true,
            Filter = "",
            OrderBy = { "" }
        };
    
        options.Select.Add("HotelId");
        options.Select.Add("HotelName");
        options.Select.Add("Address/City");
    
        response = srchclient.Search<Hotel>("*", options);
        WriteDocuments(response);
    
  3. 在第二个查询中,搜索某个术语,添加筛选器(用于选择评级大于 4 的文档),然后按评级降序排序。In the second query, search on a term, add a filter that selects documents where Rating is greater than 4, and then sort by Rating in descending order. 筛选器是布尔表达式,该表达式通过索引中的 IsFilterable 字段求值。Filter is a boolean expression that is evaluated over IsFilterable fields in an index. 筛选器查询包括或排除值。Filter queries either include or exclude values. 同样,筛选器查询没有关联的相关性分数。As such, there is no relevance score associated with a filter query.

    Console.WriteLine("Query #2: Search on 'hotels', filter on 'Rating gt 4', sort by Rating in descending order...\n");
    
    options = new SearchOptions()
    {
        Filter = "Rating gt 4",
        OrderBy = { "Rating desc" }
    };
    
    options.Select.Add("HotelId");
    options.Select.Add("HotelName");
    options.Select.Add("Rating");
    
    response = srchclient.Search<Hotel>("hotels", options);
    WriteDocuments(response);
    
  4. 第三个查询演示了 searchFields,可用于将全文搜索操作的作用域限定为特定字段。The third query demonstrates searchFields, used to scope a full text search operation to specific fields.

    Console.WriteLine("Query #3: Limit search to specific fields (pool in Tags field)...\n");
    
    options = new SearchOptions()
    {
        SearchFields = { "Tags" }
    };
    
    options.Select.Add("HotelId");
    options.Select.Add("HotelName");
    options.Select.Add("Tags");
    
    response = srchclient.Search<Hotel>("pool", options);
    WriteDocuments(response);
    
  5. 第四个查询演示了 Facet,可用于构建分面导航结构。The fourth query demonstrates facets, which can be used to structure a faceted navigation structure.

     Console.WriteLine("Query #4: Facet on 'Category'...\n");
    
     options = new SearchOptions()
     {
         Filter = ""
     };
    
     options.Facets.Add("Category");
    
     options.Select.Add("HotelId");
     options.Select.Add("HotelName");
     options.Select.Add("Category");
    
     response = srchclient.Search<Hotel>("*", options);
     WriteDocuments(response);
    
  6. 在第五个查询中,返回一个特定文档。In the fifth query, return a specific document. 文档查找是对结果集中的 OnClick 事件的典型响应。A document lookup is a typical response to OnClick event in a result set.

     Console.WriteLine("Query #5: Look up a specific document...\n");
    
     Response<Hotel> lookupResponse;
     lookupResponse = srchclient.GetDocument<Hotel>("3");
    
     Console.WriteLine(lookupResponse.Value.HotelId);
    
  7. 最后一个查询显示了“自动完成”的语法,它模拟部分用户输入,即“sa”,该输入解析为 sourceFields 中的两个可能的匹配项,与你在索引中定义的建议器相关联。The last query shows the syntax for autocomplete, simulating a partial user input of "sa" that resolves to two possible matches in the sourceFields associated with the suggester you defined in the index.

     Console.WriteLine("Query #6: Call Autocomplete on HotelName that starts with 'sa'...\n");
    
     var autoresponse = srchclient.Autocomplete("sa", "sg");
     WriteDocuments(autoresponse);
    
  8. 将 RunQueries 添加到 Main()。Add RunQueries to Main().

    // Call the RunQueries method to invoke a series of queries
    Console.WriteLine("Starting queries...\n");
    RunQueries(srchclient);
    
    // End the program
    Console.WriteLine("{0}", "Complete. Press any key to end this program...\n");
    Console.ReadKey();
    

前面的查询显示了在查询中匹配术语的多种方式:全文搜索、筛选器和自动完成。The previous queries show multiple ways of matching terms in a query: full-text search, filters, and autocomplete.

全文搜索和筛选器是使用 SearchClient.Search 方法执行的。Full text search and filters are performed using the SearchClient.Search method. 搜索查询可在 searchText 字符串中传递,而筛选表达式则可在 SearchOptions 类的 Filter 属性中传递。A search query can be passed in the searchText string, while a filter expression can be passed in the Filter property of the SearchOptions class. 若要筛选但不搜索,只需传递 "*" 作为 Search 方法的 searchText 参数。To filter without searching, just pass "*" for the searchText parameter of the Search method. 若要搜索但不筛选,则不设置 Filter 属性,或不在 SearchOptions 实例中传递。To search without filtering, leave the Filter property unset, or do not pass in a SearchOptions instance at all.

运行程序Run the program

按 F5 可重新生成应用并完整运行该程序。Press F5 to rebuild the app and run the program in its entirety.

输出包含 Console.WriteLine 中的消息,并添加了查询信息和结果。Output includes messages from Console.WriteLine, with the addition of query information and results.

清理资源Clean up resources

在自己的订阅中操作时,最好在项目结束时确定是否仍需要已创建的资源。When you're working in your own subscription, it's a good idea at the end of a project to identify whether you still need the resources you created. 持续运行资源可能会产生费用。Resources left running can cost you money. 可以逐个删除资源,也可以删除资源组以删除整个资源集。You can delete resources individually or delete the resource group to delete the entire set of resources.

可以使用左侧导航窗格中的“所有资源”或“资源组”链接 ,在门户中查找和管理资源。You can find and manage resources in the portal, using the All resources or Resource groups link in the left-navigation pane.

如果使用的是免费服务,请记住只能设置三个索引、索引器和数据源。If you are using a free service, remember that you are limited to three indexes, indexers, and data sources. 可以在门户中删除单个项目,以不超出此限制。You can delete individual items in the portal to stay under the limit.

后续步骤Next steps

在此 C# 快速入门中,你已完成一系列任务,即创建索引、使用文档加载索引并运行查询。In this C# quickstart, you worked through a set of tasks to create an index, load it with documents, and run queries. 在不同的阶段,我们采用快捷方式来简化代码,从而实现可读性和可理解性。At different stages, we took shortcuts to simplify the code for readability and comprehension. 如果你已理解这些基本概念,我们建议阅读下一篇文章,探索替代方法和概念,进一步加深你的理解。If you are comfortable with the basic concepts, we recommend the next article for an exploration of alternative approaches and concepts that will deepen your knowledge.