# Autocomplete: Making Search More User-Friendly

Learn how to build fast, production-ready autocomplete with Manticore Search using CALL AUTOCOMPLETE, CALL KEYWORDS, infix tricks, and integration patterns.

### 介绍

自动补全看起来可能是一个小功能，但它有巨大的影响。它节省了输入时间，帮助人们更快地找到他们想要的内容，并防止了“无结果”的搜索。  

本文是使用 **Manticore Search** 构建自动补全的实用指南。你将看到如何使用：  
- `CALL AUTOCOMPLETE` 和 `/autocomplete` HTTP 端点  
- 使用 `CALL KEYWORDS` 进行快速字典查找  
- 使用前缀搜索和高亮进行句子补全  
- 在生产环境中运行自动补全的实用技巧  

![自动补全示例](./autocomplete-the-predictive-search/ice-cream.png)

## 谁应该阅读本指南

本指南适用于向在线商店、文档网站或内部工具添加搜索建议的开发人员——特别是如果你使用或计划使用 Manticore Search。示例是实际操作的，可以直接在你的数据上尝试。

## 快速决策指南

- **使用 `CALL AUTOCOMPLETE`（或 `POST /autocomplete`）** 当你需要从索引数据中获取具有拼写容错、多词建议时。  
- **使用 `CALL KEYWORDS`** 当你需要闪电般的、类似字典的单字或非常短语的补全时。  
- **使用前缀搜索与高亮** 当你需要短语或句子级别的建议（例如显示文档句子的其余部分）时。  
- **启用 `bigram_index`** 如果你需要双词预测（预测“下一个词”）。  

## 先决条件和注意事项

- [Buddy](https://manual.manticoresearch.com/Installation/Manticore_Buddy#Manticore-Buddy) 是 `CALL AUTOCOMPLETE` 和 `/autocomplete` HTTP 端点所必需的。如果未安装 Buddy，这些调用将无法工作。
- 目标表必须启用前缀（`min_infix_len`）。Manticore 会缓存 `min_infix_len` 检查约 30 秒以提高性能；如果你修改 `min_infix_len`（例如在调整搜索性能或在现有表上启用自动补全时），在该窗口期间可能会看到短暂的不一致。
- `CALL AUTOCOMPLETE` 仅缓存成功的检查。如果你禁用 `min_infix_len` 或删除表，后续的自动补全调用可能会在缓存更新或出现错误之前表现陈旧。

---

## CALL AUTOCOMPLETE — 快速示例（SQL）

这是从你的索引中获取建议候选的最直接方式。

```sql
CALL AUTOCOMPLETE('ice', 'products');
```

典型的查询结果集包含一个名为 `query` 的单列：

```
+---------------+
| query         |
+---------------+
| ice           |
| ice cream     |
| iceberg       |
| iceland       |
+---------------+
```

### CALL AUTOCOMPLETE 的工作原理（简要）

`CALL AUTOCOMPLETE` 是一个高级便捷功能，它协调 Manticore 内部的多个低级原语，以快速生成相关建议。实际上，它结合了：

- `CALL KEYWORDS`：快速字典查找，返回前缀/前缀标记候选和统计信息（`docs`/`hits`）。这是从索引字典中获得强、低延迟候选的关键。
- 建议例程（历史上通过 `CALL SUGGEST` / `CALL QSUGGEST` 暴露）：生成标记（尤其是最后一个词）的模糊变体并帮助生成容错替代方案的例程。
- 模糊搜索逻辑：与模糊搜索引入的相同编辑距离（Levenshtein）和排名启发式方法，自动补全流程会重用这些方法对候选进行排序和过滤。

这些组件协同工作：关键词提供候选，建议/模糊例程扩展和修复它们，模糊逻辑按距离和流行度对结果进行排序/过滤。当启用时，键盘布局猜测会在模糊计算之前应用，以便在计算模糊性之前纠正布局错误的输入。

### 何时不直接调用 CALL KEYWORDS

`CALL KEYWORDS` 是一个极快的工具，当你需要严格的字典补全（精确的前缀/前缀匹配）时非常出色。然而，它不提供拼写容错或多词建议组合。对于多词、容错建议，优先使用 `CALL AUTOCOMPLETE`；使用 `CALL KEYWORDS` 用于非常短的前缀、热门列表或当你明确想要仅字典结果时。

### 选项映射（高级）

- `CALL AUTOCOMPLETE` 中的 `fuzziness` 对应于类似建议 API 中 `max_edits` 的编辑距离限制。
- `preserve` 控制是否在模糊匹配旁边保留非模糊标记。
- `layouts` 启用在模糊评估之前的键盘布局猜测。

注意：此处描述的内部原语组合反映了实现方法，但应将其视为实现细节——在设计应用程序时，请依赖文档中 `CALL AUTOCOMPLETE` API 和选项，而不是内部行为。

这些内部组合就是为什么 `CALL AUTOCOMPLETE` 通常比单独运行 `CALL KEYWORDS` 提供更好、更实用的建议。
### HTTP/JSON 示例（Buddy）

如果你更喜欢 HTTP 或有使用 JSON 的前端，请使用 Buddy 提供的 `/autocomplete` 端点：

```json
POST /autocomplete
{
  "table": "products",
  "query": "ice"
}
```

JSON 响应返回一个建议补全（和元数据）数组，你可以在 UI 中展示。

## CALL AUTOCOMPLETE 选项详解

`CALL AUTOCOMPLETE` 接受多个选项来调整行为。以下是你最常使用的选项：

- `layouts`: 以逗号分隔的键盘布局代码（`us`、`ru`、`ua`、`de`、`fr` 等）。用于检测布局输入错误（例如，在英文布局下输入 "ghbdtn" 但实际想输入 "привет" - 俄语中表示 "hello"）。需要至少两个布局来比较字符位置。
- `fuzziness`: 0、1 或 2（默认 2）。匹配拼写错误的最大 Levenshtein 距离。设为 0 以禁用模糊匹配。
- `preserve`: 0 或 1（默认 0）。如果设为 1，建议内容将包括未获得模糊匹配的单词（适用于保留专有名词或短词）。
- `prepend` / `append`: 布尔值（0/1）。如果为真，在最后一个单词前/后添加星号以扩展前缀/后缀（例如，`prepend` -> `*word`，`append` -> `word*`）。
- `expansion_len`: 扩展最后一个标记的字符数（默认 10）。控制将考虑扩展的字符数量。

### 带选项的示例（SQL）

```sql
CALL AUTOCOMPLETE('ghbdtn', 'comments', 'us,ru' as layouts, 1 as fuzziness);
```

这将检测到 "ghbdtn" 是 "привет"（俄语中表示 "hello"）的布局输入错误，并应用模糊匹配以找到正确的建议。

---

## 调用关键词 —— 基于标记的补全

当您只需要建议单个单词（或结尾）并希望获得最大速度时，`CALL KEYWORDS` 是一个极好的替代方案。它使用索引字典而不是扫描文档，这使其非常高效。

基本语法：

```sql
CALL KEYWORDS('ca*', 'products', 1 AS stats, 'hits' AS sort_mode);
```

这将返回带有 `tokenized` 和 `normalized` 形式的行以及可选的统计信息（`docs`、`hits`）。按 `hits` 排序可显示最受欢迎的补全。

示例结果（说明性）：

```
+------+-----------+------------+------+------+
| qpos | tokenized | normalized | docs | hits |
+------+-----------+------------+------+------+
| 1    | ca*       | cat        | 1    | 2    |
| 1    | ca*       | carnivorous| 1    | 1    |
+------+-----------+------------+------+------+
```

### bigram_index 技巧

如果您的表启用了 `bigram_index`，索引会存储相邻单词对作为标记。这使您可以建议可能的下一个单词（“预测下一个单词”），而不仅仅是完成当前标记。这是一种简单但强大的方法，可以在不添加外部 ML 模型的情况下改进多词建议。

---

## 使用中缀搜索和高亮的句子补全

对于短语或句子尾部的补全（例如，从文档中自动补全句子的剩余部分），使用带有通配符的中缀查询并高亮匹配部分。例如，查找字段以输入片段开头的文档：

- 用户输入时可以发出的查询示例：
  - `^"m*"`
  - `^"my *"`
  - `^"my c*"`
  - `^"my ca*"`

使用 `^` 锚点从开头匹配，`*` 扩展其余部分。启用高亮后，您可以提取匹配部分并将其作为建议呈现（例如："My cat loves ..."）。

当您希望建议是完整短语或文档片段而不是孤立标记时，这种方法最为适用。

---

## 集成模式（前端 → 后端）

一个最小且适合生产的流程如下：

1. 对用户输入进行防抖（150–300 毫秒）以避免过多请求。
2. 对于 1–2 个字符，使用 `CALL KEYWORDS` 或热列表。
3. 对于 3 个及以上字符，调用 `/autocomplete` 或 `CALL AUTOCOMPLETE`。根据用户需求包含适当的选项（`layouts`、`fuzziness`）。
4. 显示带有高亮匹配的建议。
5. 跟踪点击并按受欢迎程度或业务规则重新排序建议。

### UX 建议

- 在桌面端显示 6–10 个建议，在移动端显示 3–5 个。
- 如果相关，按类型（例如产品、文档、人员）进行分组。
- 始终提供回退选项：例如，“搜索 {query}”。

---

## 生产提示

- `min_infix_len`：确保根据您的语言和使用情况正确设置此值。非常小的值会增加索引大小和 CPU 使用率；非常大的值会降低匹配灵活性。
- 缓存：允许约 30 秒以使更改（如 `min_infix_len`）生效。
- 限流：对于高流量使用请求节流或内存缓存。
- 索引维护：考虑预计算一个“顶级建议”表以处理最常见的前缀。

---

## 故障排除检查表

如果自动补全行为异常：

1. 验证是否已安装 Buddy（如果使用 `/autocomplete`）。
2. 确认表已设置 `min_infix_len` 并启用了中缀。
3. 如果最近更改了表设置，请等待 30 秒后重试以允许内部缓存刷新。
4. 尝试对相同前缀使用 `CALL KEYWORDS` 以确保字典中存在标记。
5. 检查可能影响结果的编码和分词设置（`morphology`、`stopwords`）。

---

## 示例：完整流程（示例）

用户输入："ice c"

客户端（防抖后）发送：

```json
POST /autocomplete
{
  "table": "products",
  "query": "ice c",
  "options": { "fuzziness": 1 }
}
```

服务器返回建议，如 "ice cream"、"ice coffee"、"ice cold"。UI 显示这些建议；选择后，客户端导航到搜索 URL 如 `/search?q=ice+cream` 或使用所选建议获取产品详情。

---
## 结论

自动补全是提供巨大价值的小型用户体验功能：更快的搜索、更少的死胡同和更高的用户满意度。使用 Manticore Search，您有实际的选择来实现建议 —— 从快速、字典驱动的 `CALL KEYWORDS` 到更灵活、容错的 `CALL AUTOCOMPLETE`（以及通过 Buddy 的 HTTP `/autocomplete` 端点）。使用此处描述的方法，根据您的应用程序平衡延迟、准确性和资源成本。

将本文中的示例与您的索引进行测试，监控建议质量，并调整选项如 `fuzziness` 和 `min_infix_len` 以匹配您的数据和用户。如果您需要一个轻量级的起点，请为最常见的前缀构建一个简短的热列表，并将较长的输入通过 `CALL AUTOCOMPLETE` 路由。

使用自动补全构建更智能、更快的搜索。
