使用 Azure 认知搜索将自动完成和建议添加到客户端应用Add autocomplete and suggestions to client apps using Azure Cognitive Search

“键入时搜索”是提高查询效率的一种常用技术。Search-as-you-type is a common technique for improving query productivity. 在 Azure 认知搜索中,此体验是通过“自动完成”支持的。自动完成可根据部分输入来完成某个字词或短语(使用“microsoft”来补全“micro”)。In Azure Cognitive Search, this experience is supported through autocomplete, which finishes a term or phrase based on partial input (completing "micro" with "microsoft"). 另一种用户体验是“建议”或匹配文档的简短列表(返回具有某个 ID 的书名,以便可以链接到该书的详细信息页)。A second user experience is suggestions, or a short list of matching documents (returning book titles with an ID so that you can link to a detail page about that book). 自动完成和建议都是根据索引中的匹配项预测的。Both autocomplete and suggestions are predicated on a match in the index. 服务不会提供返回零个结果的查询。The service won't offer queries that return zero results.

若要在 Azure 认知搜索中实现这些体验,需要:To implement these experiences in Azure Cognitive Search, you will need:

  • 在索引架构中嵌入的建议器定义。A suggester definition that's embedded in the index schema.
  • 一个在请求中指定自动完成建议 API 的查询。A query specifying Autocomplete or Suggestions API on the request.
  • 一个用于在客户端应用中处理“边键入边搜索”交互的 UI 控件。A UI control to handle search-as-you-type interactions in your client app. 对于此目的,我们建议使用现有的 JavaScript 库。We recommend using an existing JavaScript library for this purpose.

在 Azure 认知搜索中,自动完成的查询和建议的结果是在搜索索引中从已向建议器注册的选定字段中检索的。In Azure Cognitive Search, autocompleted queries and suggested results are retrieved from the search index, from selected fields that you have registered with a suggester. 建议器是索引的一部分,它指定哪些字段将提供完成查询和/或建议结果的内容。A suggester is part of the index, and it specifies which fields will provide content that either completes a query, suggests a result, or does both. 创建并加载索引后,将在内部创建建议器数据结构,以存储用于对部分查询进行匹配的前缀。When the index is created and loaded, a suggester data structure is created internally to store prefixes used for matching on partial queries. 对于建议,选择唯一或者至少不重复的适当字段对于实现该体验至关重要。For suggestions, choosing suitable fields that are unique, or at least not repetitive, is essential to the experience. 有关详细信息,请参阅创建建议器For more information, see Create a suggester.

本文的剩余内容将重点介绍查询和客户端代码。The remainder of this article is focused on queries and client code. 其中使用了 JavaScript 和 C# 来演示关键点。It uses JavaScript and C# to illustrate key points. 使用了 REST API 示例来简要演示每个操作。REST API examples are used to concisely present each operation. 有关端到端代码示例的链接,请参阅后续步骤For links to end-to-end code samples, see Next steps.

设置请求Set up a request

请求的元素包括一个“边键入边搜索”API、一个部分查询和一个建议器。Elements of a request include one of the search-as-you-type APIs, a partial query, and a suggester. 以下脚本使用“自动完成 REST API”作为示例来演示请求的组成部分。The following script illustrates components of a request, using the Autocomplete REST API as an example.

POST /indexes/myxboxgames/docs/autocomplete?search&api-version=2020-06-30
{
  "search": "minecraf",
  "suggesterName": "sg"
}

“suggesterName”提供建议器感知的字段,用以完成字词或建议。The "suggesterName" gives you the suggester-aware fields used to complete terms or suggestions. 具体对于建议而言,字段列表应该由那些在匹配结果之间中提供明确选择的字段构成。For suggestions in particular, the field list should be composed of those that offer clear choices among matching results. 在销售电脑游戏的站点上,该字段可能是游戏名称。On a site that sells computer games, the field might be the game title.

“search”参数提供了部分查询,其中的字符通过 jQuery 自动完成控件馈送到查询请求。The "search" parameter provides the partial query, where characters are fed to the query request through the jQuery Autocomplete control. 在上面的示例中,“minecraf”静态演示了控件可以传入的内容。In the above example, "minecraf" is a static illustration of what the control might have passed in.

API 不会对部分查询施加最小长度要求;查询长度可以短至一个字符。The APIs do not impose minimum length requirements on the partial query; it can be as little as one character. 但是,jQuery 自动完成提供了一个最小长度。However, jQuery Autocomplete provides a minimum length. 通常最少包含两到三个字符。A minimum of two or three characters is typical.

匹配项出现在输入字符串中任意位置的字词的开头。Matches are on the beginning of a term anywhere in the input string. 假如输入字符串为“the quick brown fox”,则自动完成和建议都会匹配部分字词“the”、“quick”、“brown”或“fox”,但不匹配字词中包含的部分字符,例如“rown”或“ox”。Given "the quick brown fox", both autocomplete and suggestions will match on partial versions of "the", "quick", "brown", or "fox" but not on partial infix terms like "rown" or "ox". 此外,每次匹配都会设置下游扩展的范围。Furthermore, each match sets the scope for downstream expansions. 部分查询“quick br”会匹配“quick brown”或“quick bread”,但“brown”或“bread”本身都不是匹配项,除非它们前面带有“quick”。A partial query of "quick br" will match on "quick brown" or "quick bread", but neither "brown" or "bread" by themselves would be match unless "quick" precedes them.

用于“边键入边搜索”的 APIAPIs for search-as-you-type

请参考 REST 和 .NET SDK 参考页的以下链接:Follow these links for the REST and .NET SDK reference pages:

构建响应Structure a response

对自动完成和建议的响应是你可能对模式的期望:自动完成返回字词列表,建议返回字词加上文档 ID,以便你提取文档(使用查找文档 API 提取详细信息页的特定文档)。Responses for autocomplete and suggestions are what you might expect for the pattern: Autocomplete returns a list of terms, Suggestions returns terms plus a document ID so that you can fetch the document (use the Lookup Document API to fetch the specific document for a detail page).

响应格式由请求中的参数确定:Responses are shaped by the parameters on the request:

  • 对于自动完成,请设置 autocompleteMode 来确定是要对一个还是两个字词执行文本完成。For Autocomplete, set the autocompleteMode to determine whether text completion occurs on one or two terms.

  • 对于建议,请设置 $select 以返回包含唯一值或区别性值(如名称和说明)的字段。For Suggestions, set $select to return fields containing unique or differentiating values, such as names and description. 避免使用包含重复值(例如类别或城市)的字段。Avoid fields that contain duplicate values (such as a category or city).

以下附加参数适用于自动完成和建议,但对于建议(尤其是建议器包含多个字段的情况)可能更有必要。The following additional parameters apply to both autocomplete and suggestions, but are perhaps more necessary for suggestions, especially when a suggester includes multiple fields.

参数Parameter 使用情况Usage
searchFieldssearchFields 将查询限制为特定字段。Constrain the query to specific fields.
$filter$filter 对结果集应用匹配条件 ($filter=Category eq 'ActionAdventure')。Apply match criteria on the result set ($filter=Category eq 'ActionAdventure').
$top$top 将结果限制为特定的数量 ($top=5)。Limit the results to a specific number ($top=5).

添加用户交互代码Add user interaction code

自动填充查询字词或删除匹配链接的列表需要用户交互代码(通常为 JavaScript),这些代码可以使用来自外部源(例如,针对 Azure 搜索认知索引运行的自动完成或建议查询)的请求。Auto-filling a query term or dropping down a list of matching links requires user interaction code, typically JavaScript, that can consume requests from external sources, such as autocomplete or suggestion queries against an Azure Search Cognitive index.

尽管你可以在本机编写此代码,但使用现有 JavaScript 库中的函数会方便得多,如下所示。Although you could write this code natively, it's much easier to use functions from existing JavaScript library, such as one of the following.

  • 建议代码片段中显示的自动完成小组件 (jQuery UI)Autocomplete widget (jQuery UI) appears in the Suggestion code snippet. 你可以创建搜索框,然后在使用自动完成小组件的 JavaScript 函数中引用它。You can create a search box, and then reference it in a JavaScript function that uses the Autocomplete widget. 该小组件中的属性设置源(自动完成或建议函数)、执行操作之前的输入字符的最小长度,以及位置。Properties on the widget set the source (an autocomplete or suggestions function), minimum length of input characters before action is taken, and positioning.

  • 自动完成代码片段中显示的 XDSoft 自动完成插件XDSoft Autocomplete plug-in appears in the Autocomplete code snippet.

  • JavaScript 教程 和代码示例中显示的建议suggestions appears in the JavaScript tutorial and code sample.

使用客户端中的这些库来创建支持建议和自动完成的搜索框。Use these libraries in the client to create a search box supporting both suggestions and autocomplete. 然后,在搜索框中收集的输入可以与搜索服务上的建议和自动完成操作配对。Inputs collected in the search box can then be paired with suggestions and autocomplete actions on the search service.

建议Suggestions

本部分逐步讲解建议的结果的一个实现,从搜索框定义开始。This section walks you through an implementation of suggested results, starting with the search box definition. 此外,它还演示了如何使用脚本来调用本文中引用的第一个 JavaScript 自动完成库。It also shows how and script that invokes the first JavaScript autocomplete library referenced in this article.

假设你有 jQuery UI Autocomplete 库并有一个以 C# 编写的 MVC 项目,则可以在 Index.cshtml 文件中使用 JavaScript 来定义搜索框。Assuming the jQuery UI Autocomplete library and an MVC project in C#, you could define the search box using JavaScript in the Index.cshtml file. 该库通过异步调用 MVC 控制器来检索建议,将“边键入边搜索”交互添加到搜索框。The library adds the search-as-you-type interaction to the search box by making asynchronous calls to the MVC controller to retrieve suggestions.

在 \Views\Home 文件夹下的 Index.cshtml 中,用于创建搜索框的代码行可能如下所示:In Index.cshtml under the folder \Views\Home, a line to create a search box might be as follows:

<input class="searchBox" type="text" id="searchbox1" placeholder="search">

此示例是一个简单的输入文本框,包含用于设置样式的类、JavaScript 引用的 ID,以及占位符文本。This example is a simple input text box with a class for styling, an ID to be referenced by JavaScript, and placeholder text.

在同一文件中,嵌入引用搜索框的 JavaScript。Within the same file, embed JavaScript that references the search box. 以下函数调用建议 API,该 API 根据部分字词输入来请求建议的匹配文档:The following function calls the Suggest API, which requests suggested matching documents based on partial term inputs:

$(function () {
    $("#searchbox1").autocomplete({
        source: "/home/suggest?highlights=false&fuzzy=false&",
        minLength: 3,
        position: {
            my: "left top",
            at: "left-23 bottom+10"
        }
    });
});

source 告知 jQuery UI Autocomplete 函数要从何处获取显示在搜索框下的项列表。The source tells the jQuery UI Autocomplete function where to get the list of items to show under the search box. 由于此项目是一个 MVC 项目,因此它将调用 HomeController.cs 中的 Suggest 函数,该函数包含用于返回查询建议的逻辑 。Since this project is an MVC project, it calls the Suggest function in HomeController.cs that contains the logic for returning query suggestions. 此函数还会传递一些参数来控制突出显示内容、模糊匹配项和字词。This function also passes a few parameters to control highlights, fuzzy matching, and term. 自动完成 JavaScript API 会添加字词参数。The autocomplete JavaScript API adds the term parameter.

minLength: 3 确保仅当搜索框中至少有三个字符时,才显示建议。The minLength: 3 ensures that recommendations will only be shown when there are at least three characters in the search box.

启用模糊匹配Enable fuzzy matching

使用模糊搜索可以根据接近的匹配项获取结果,即使用户在搜索框中拼错了单词。Fuzzy search allows you to get results based on close matches even if the user misspells a word in the search box. 编辑距离为 1,这意味着,用户输入与匹配项之间的最大差异只能是一个字符。The edit distance is 1, which means there can be a maximum discrepancy of one character between the user input and a match.

source: "/home/suggest?highlights=false&fuzzy=true&",

启用突出显示Enable highlighting

突出显示将字体样式应用于结果中与输入对应的字符。Highlighting applies font style to the characters in the result that correspond to the input. 例如,如果部分输入为“micro”,则结果将显示为 microsoft、microscope 等 。For example, if the partial input is "micro", the result would appear as micro soft, micro scope, and so forth. 突出显示基于 Suggestion 函数中内联定义的 HighlightPreTag 和 HighlightPostTag 参数。Highlighting is based on the HighlightPreTag and HighlightPostTag parameters, defined inline with the Suggestion function.

source: "/home/suggest?highlights=true&fuzzy=true&",

Suggest 函数Suggest function

如果使用 C# 和 MVC 应用程序,可以在 Controllers 目录下的 HomeController.cs 文件中为建议的结果创建类。If you are using C# and an MVC application, HomeController.cs file under the Controllers directory is where you might create a class for suggested results. 在 .NET 中,Suggest 函数基于 SuggestAsync 方法In .NET, a Suggest function is based on the SuggestAsync method. 有关 .NET SDK 的详细信息,请参阅如何从 .NET 应用程序使用 Azure 认知搜索For more information about the .NET SDK, see How to use Azure Cognitive Search from a .NET Application.

InitSearch 方法在 Azure 认知搜索服务中创建经过身份验证的 HTTP 索引客户端。The InitSearch method creates an authenticated HTTP index client to the Azure Cognitive Search service. SuggestOptions 类的属性决定了要搜索并要在结果中返回的字段、匹配项的数量以及是否使用模糊匹配。Properties on the SuggestOptions class determine which fields are searched and returned in the results, the number of matches, and whether fuzzy matching is used.

对于自动完成功能,模糊匹配限制为一个编辑距离(一个省略的或错误放置的字符)。For autocomplete, fuzzy matching is limited to one edit distance (one omitted or misplaced character). 请注意,自动完成查询中的模糊匹配有时会产生意外的结果,具体取决于索引大小及其分片方式。Note that fuzzy matching in autocomplete queries can sometimes produce unexpected results depending on index size and how it's sharded. 有关详细信息,请参阅分区和分片的概念For more information, see partition and sharding concepts.

public async Task<ActionResult> SuggestAsync(bool highlights, bool fuzzy, string term)
{
    InitSearch();

    var options = new SuggestOptions()
    {
        UseFuzzyMatching = fuzzy,
        Size = 8,
    };

    if (highlights)
    {
        options.HighlightPreTag = "<b>";
        options.HighlightPostTag = "</b>";
    }

    // Only one suggester can be specified per index.
    // The suggester for the Hotels index enables autocomplete/suggestions on the HotelName field only.
    // During indexing, HotelNames are indexed in patterns that support autocomplete and suggested results.
    var suggestResult = await _searchClient.SuggestAsync<Hotel>(term, "sg", options).ConfigureAwait(false);

    // Convert the suggest query results to a list that can be displayed in the client.
    List<string> suggestions = suggestResult.Value.Results.Select(x => x.Text).ToList();

    // Return the list of suggestions.
    return new JsonResult(suggestions);
}

SuggestAsync 函数采用两个参数,用于确定是返回命中突出显示,还是在搜索词输入的基础上使用模糊匹配。The SuggestAsync function takes two parameters that determine whether hit highlights are returned or fuzzy matching is used in addition to the search term input. 建议的结果中最多可以包含 8 个匹配项。Up to eight matches can be included in suggested results. 该方法创建 SuggestOptions 对象,该对象随后会传递给 Suggest API。The method creates a SuggestOptions object, which is then passed to the Suggest API. 然后,结果将转换成 JSON,以便在客户端中显示。The result is then converted to JSON so it can be shown in the client.

自动完成Autocomplete

到目前为止,搜索 UX 代码以建议为中心。So far, the search UX code has been centered on suggestions. 下一个代码块演示了如何使用 XDSoft jQuery UI Autocomplete 函数实现自动完成,该函数传入一个请求来实现 Azure 认知搜索自动完成。The next code block shows autocomplete, using the XDSoft jQuery UI Autocomplete function, passing in a request for Azure Cognitive Search autocomplete. 与建议一样,在 C# 应用程序中,支持用户交互的代码位于 index.cshtml 中。As with the suggestions, in a C# application, code that supports user interaction goes in index.cshtml.

$(function () {
    // using modified jQuery Autocomplete plugin v1.2.8 https://xdsoft.net/jqplugins/autocomplete/
    // $.autocomplete -> $.autocompleteInline
    $("#searchbox1").autocompleteInline({
        appendMethod: "replace",
        source: [
            function (text, add) {
                if (!text) {
                    return;
                }

                $.getJSON("/home/autocomplete?term=" + text, function (data) {
                    if (data && data.length > 0) {
                        currentSuggestion2 = data[0];
                        add(data);
                    }
                });
            }
        ]
    });

    // complete on TAB and clear on ESC
    $("#searchbox1").keydown(function (evt) {
        if (evt.keyCode === 9 /* TAB */ && currentSuggestion2) {
            $("#searchbox1").val(currentSuggestion2);
            return false;
        } else if (evt.keyCode === 27 /* ESC */) {
            currentSuggestion2 = "";
            $("#searchbox1").val("");
        }
    });
});

Autocomplete 函数Autocomplete function

自动完成功能基于 AutocompleteAsync 方法Autocomplete is based on the AutocompleteAsync method. 与建议一样,此代码块位于 HomeController.cs 文件中。As with suggestions, this code block would go in the HomeController.cs file.

public async Task<ActionResult> AutoCompleteAsync(string term)
{
    InitSearch();

    // Setup the autocomplete parameters.
    var ap = new AutocompleteOptions()
    {
        Mode = AutocompleteMode.OneTermWithContext,
        Size = 6
    };
    var autocompleteResult = await _searchClient.AutocompleteAsync(term, "sg", ap).ConfigureAwait(false);

    // Convert the autocompleteResult results to a list that can be displayed in the client.
    List<string> autocomplete = autocompleteResult.Value.Results.Select(x => x.Text).ToList();

    return new JsonResult(autocomplete);
}

Autocomplete 函数采用搜索字词输入。The Autocomplete function takes the search term input. 该方法创建 AutoCompleteParameters 对象The method creates an AutoCompleteParameters object. 然后,结果将转换成 JSON,以便在客户端中显示。The result is then converted to JSON so it can be shown in the client.

后续步骤Next steps

访问以下链接,获取端到端的说明或演示上述两种“边键入边搜索”体验的代码。Follow these links for end-to-end instructions or code demonstrating both search-as-you-type experiences. 该示例演示了建议和自动完成组合的混合实现。The sample demonstrates the hybrid implementation of suggestions and autocomplete together.