向客户端应用添加自动完成和建议Add autocomplete and suggestions to client apps

“边键入边搜索”是提高用户发起的查询的工作效率的一种常用技术。Search-as-you-type is a common technique for improving the productivity of user-initiated queries. 在 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 的书名,以便可以链接到详细信息页)**。Another form is suggestions: a short list of matching documents (returning book titles with an ID so that you can link to a detail page). 自动完成和建议都是根据索引中的匹配项预测的。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 on the back end.
  • 一个在请求中指定自动完成建议 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 autocompleteMode to determine whether text completion occurs on one or two terms. 对于建议,你选择的字段确定了响应的内容。For Suggestions, the field you choose determines the contents of the response.

对于建议,应进一步优化响应,以避免重复或看似无关的结果。For suggestions, you should further refine the response to avoid duplicates or what appears to be unrelated results. 若要控制结果,请在请求中包含更多参数。To control results, include more parameters on the request. 以下参数适用于自动完成和建议,但对于建议(尤其是建议器包含多个字段的情况)可能更有必要。The following parameters apply to both autocomplete and suggestions, but are perhaps more necessary for suggestions, especially when a suggester includes multiple fields.

参数Parameter 使用情况Usage
$select$select 如果建议器中有多个 sourceField****,请使用 $select**** 来选择由哪个字段提供值 ($select=GameTitle)。If you have multiple sourceFields in a suggester, use $select to choose which field contributes values ($select=GameTitle).
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. 本文演示了其中的两个函数,一个用于建议,另一个用于自动完成。This article demonstrates two, one for suggestions and another for autocomplete.

  • 建议示例中使用了自动完成小组件 (jQuery UI)Autocomplete widget (jQuery UI) is used in the Suggestion example. 你可以创建搜索框,然后在使用自动完成小组件的 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 is used the Autocomplete example.

我们将使用这些库来生成支持建议和自动完成的搜索框。We use these libraries to build the search box supporting both suggestions and autocomplete. 搜索框中收集的输入将与建议和自动完成操作进行配对。Inputs collected in the search box are paired with suggestions and autocomplete actions.

建议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 microsoft, microscope, 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 函数基于 DocumentsOperationsExtensions.Suggest 方法In .NET, a Suggest function is based on the DocumentsOperationsExtensions.Suggest method.

InitSearch 方法在 Azure 认知搜索服务中创建经过身份验证的 HTTP 索引客户端。The InitSearch method creates an authenticated HTTP index client to the Azure Cognitive Search service. 有关 .NET SDK 的详细信息,请参阅如何从 .NET 应用程序使用 Azure 认知搜索For more information about the .NET SDK, see How to use Azure Cognitive Search from a .NET Application.

public ActionResult Suggest(bool highlights, bool fuzzy, string term)
{
    InitSearch();

    // Call suggest API and return results
    SuggestParameters sp = new SuggestParameters()
    {
        Select = HotelName,
        SearchFields = HotelName,
        UseFuzzyMatching = fuzzy,
        Top = 5
    };

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

    DocumentSuggestResult resp = _indexClient.Documents.Suggest(term, "sg", sp);

    // Convert the suggest query results to a list that can be displayed in the client.
    List<string> suggestions = resp.Results.Select(x => x.Text).ToList();
    return new JsonResult
    {
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        Data = suggestions
    };
}

Suggest 函数采用两个参数,用于确定是要返回命中的突出显示内容,还是在返回搜索词输入的同时返回模糊匹配结果。The Suggest function takes two parameters that determine whether hit highlights are returned or fuzzy matching is used in addition to the search term input. 该方法创建 SuggestParameters 对象,该对象随后会传递给 Suggest API。The method creates a SuggestParameters 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.6 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

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

public ActionResult AutoComplete(string term)
{
    InitSearch();
    //Call autocomplete API and return results
    AutocompleteParameters ap = new AutocompleteParameters()
    {
        AutocompleteMode = AutocompleteMode.OneTermWithContext,
        UseFuzzyMatching = false,
        Top = 5
    };
    AutocompleteResult autocompleteResult = _indexClient.Documents.Autocomplete(term, "sg", ap);

    // Convert the Suggest results to a list that can be displayed in the client.
    List<string> autocomplete = autocompleteResult.Results.Select(x => x.Text).ToList();
    return new JsonResult
    {
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        Data = 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. 这两个代码示例都包含建议和自动完成的混合实现。Both code examples include hybrid implementations of suggestions and autocomplete together.