# New fuzzy search and autocomplete in Manticore Search

### TL;DR

我们很高兴在 Manticore Search 中引入两个重要新功能：**模糊搜索**和**查询建议**（或“自动补全”）。这些功能提升了搜索能力，提供更友好的用户体验。您可以在我们的开源 [GitHub Issue Search Demo](https://github.com/manticoresoftware/manticore-github-issue-search) 中看到它们的实际效果。

* 了解 [GitHub 演示](https://github.manticoresearch.com/manticoresoftware/manticoresearch) 中的工作原理
* 探索开源项目：[GitHub 演示仓库](https://github.com/manticoresoftware/manticore-github-issue-search)

## 引言

您可能[已经阅读](/blog/manticoresearch-github-issue-search-demo/)过关于 GitHub Issue Search 演示以及我们[如何为其添加语义搜索](/blog/github-semantic-search/)的内容。最近，我们为其添加了自动补全功能。这个过程非常简单，只需进行最小的更改。更多细节请查看这篇文章：[新增模糊搜索和自动补全](/blog/github-demo-how-we-added-autocomplete/)。今天，我们想分享两个进一步提升搜索体验的新功能：**模糊搜索**和**查询建议**（也称为“自动补全”）：
- **模糊搜索**帮助用户即使有小拼写错误也能找到结果。
- **查询建议**在用户输入时建议相关短语，加快搜索过程。

这些功能不仅提升了我们 [GitHub 问题搜索工具](https://github.manticoresearch.com/) 的可用性，还展示了 Manticore Search 在处理现实世界搜索场景中的高级功能，增强用户界面并提供更相关的结果。

## 实现模糊搜索

### 拼写容错的挑战

搜索工具的一个常见痛点是，一个简单的拼写错误会导致没有结果。用户期望搜索引擎即使在他们犯小拼写错误时也能理解他们的意图。在某些情况下，可以通过使用语义搜索的上下文理解来解决这个问题，但对于传统的关键词搜索，**模糊搜索**是理想的解决方案。

### 使用 `CALL QSUGGEST` 的传统模糊匹配

历史上，Manticore Search 通过其 [`CALL QSUGGEST` 和 `CALL SUGGEST`](https://manual.manticoresearch.com/Searching/Spell_correction#CALL-QSUGGEST,-CALL-SUGGEST) 方法提供了内置的模糊匹配支持。前者允许您通过莱文斯坦距离找到给定短语中的最后一个单词，从而实现一种容错搜索，但仅适用于最后一个单词。后者仅适用于短语中的第一个单词。使用 [Manticore PHP 客户端](https://github.com/manticoresoftware/manticoresearch-php) 的示例：

```php
$params = [
    'index' => 'issue',
    'body' => [
        'query'=> 'fzzy',
        'options' => [
            'limit' => 10,
            'max_edits' => 2,
        ],
    ],
];
$response = $client->suggest($params);
```

在此代码片段中，客户端使用 `CALL SUGGEST` 函数为拼写错误的单字 "fzzy" 寻找建议。`max_edits` 参数控制输入单词与潜在建议之间的最大莱文斯坦距离。莱文斯坦距离是将一个单词转换为另一个单词所需的最小单字符编辑（插入、删除或替换）次数。通过将 `max_edits` 设置为 2，我们允许最多 2 个字符差异，从而可以在该编辑距离内找到拼写错误和相似单词。

虽然这种方法功能强大，但可能有些复杂，因为您需要在应用程序中处理函数返回的所有建议。此外，`CALL QSUGGEST` 不处理键盘布局猜测（我们稍后会讨论）。为了使模糊搜索更友好且易于集成，我们在 Manticore Search 中引入了一个新选项，允许使用特定参数进行模糊搜索，而无需额外代码或自定义逻辑。

### 新的简化模糊匹配

现在，我们有一个更简单的选项。通过在搜索查询选项中添加 `fuzzy=1`，您可以轻松启用模糊搜索。

这是一个简单示例：

```php
$client = new Client();
$index = $client->index('issues');

$query = 'fzzy serch';
$result = $index->search($query)->option('fuzzy', 1)->get();

foreach ($result as $hit) {
    echo $hit->getTitle() . "\n";
}
```

此代码为拼写错误的 "fzzy serch" 启用模糊搜索，使 Manticore 能够找到 "fuzzy search."。在我们的 [Github 搜索演示](https://github.manticoresearch.com/manticoresoftware/manticoresearch) 中，它看起来如下：

![模糊搜索示例](./new-fuzzy-search-and-autocomplete/fuzzy-search-example.png)

您可以在 [模糊搜索文档](https://manual.manticoresearch.com/Searching/Spell_correction#Fuzzy-Search) 中了解更多关于模糊匹配的信息。

## 实现查询建议（自动补全）

### 预测搜索的力量

查询建议或自动补全功能使搜索更快，并帮助用户发现他们可能没想到的相关查询：
![自动补全示例](./new-fuzzy-search-and-autocomplete/autocomplete-example.png)

### 使用 `CALL KEYWORDS` 的传统自动补全

与 `CALL QSUGGEST` 类似，Manticore Search 历史上还有另一种方法 `CALL KEYWORDS`，可用于自动补全功能。此方法允许您在表中的关键字上执行前缀和中缀匹配，提供一种简单而有效的方法来实现自动补全功能。不幸的是，它仅支持严格的前缀/后缀匹配，没有拼写容错，这意味着如果用户犯了错误，它将找不到任何关键字。以下是使用 Manticore PHP 客户端的方法：

```php
$index = 'myindex';
$query = 'pref*';

$response = $client->keywords($index, $query);

foreach ($response as $keyword) {
    echo $keyword['normalized'] . ' (docs: ' . $keyword['docs'] . ', hits: ' . $keyword['hits'] . ")\n";
}
```

在此示例中，我们使用 `CALL KEYWORDS` 方法查找 `myindex` 表中所有以 `pref` 开头的关键字。`pref*` 末尾的星号（`*`）表示前缀匹配。您也可以通过在搜索词两侧放置星号来使用中缀匹配，例如 `*some*`。

虽然这种方法在实现自动补全时快速且简单，但缺乏模糊匹配的灵活性。您需要精确匹配给定的前缀或中缀，这使其适用于需要精确关键字建议的情况。这就是新的自动补全方法发挥作用的地方，以改善搜索体验。

### 新的自动补全方法

我们引入了一种新方法，该方法从多个输入词构建建议并支持拼写错误。此方法结合了`CALL KEYWORDS`和`CALL QSUGGEST`的功能。

例如，这是在PHP客户端中使用新自动补全功能的方式：

```php
$client = new Client();
$result = $client->autocomplete([
    'body' => [
        'table' => 'issues',
        'query' => 'hllo wor',
        'options' => [
            'fuzziness' => 1,
            'layouts' => ['us', 'ru'],
        ],
    ],
]);

foreach ($result[0]['data'] as $suggestion) {
    echo $suggestion . "\n";
}
```

此代码为输入"hllo wor"建议"hello world"，考虑到拼写错误和键盘布局问题。

这是内部实现方式：我们重用了模糊搜索中的模糊逻辑来创建相关建议。该方法使用低级`CALL KEYWORDS`和`CALL QSUGGEST`功能从您的数据集中生成变体。

为了确保准确的建议，我们根据词长和可用文档数量评估距离。例如，如果用户输入"hllo wor"，而您的数据包含"hello world"，系统将由于其模糊功能建议"hello world"。这种方法帮助用户即使有拼写错误也能获得准确的建议。

您可以在[自动补全文档](https://manual.manticoresearch.com/Searching/Autocomplete)中找到有关Autocomplete的更多信息。

## 键盘布局猜测

我们还添加了键盘布局猜测功能。如果您曾经用错误的布局输入过，您会欣赏这个功能。Manticore现在可以识别您即使在切换布局时的输入意图。

我们映射了常见的键盘布局，包括语言特定的和QWERTY布局。现在，Manticore可以确定您的输入意图，即使发生布局错误也能提高准确性。

优势包括：
- 提高多语言用户的搜索准确性
- 消除因意外切换布局带来的挫败感
- 与我们的模糊搜索和自动补全功能无缝集成

## 将新功能应用于GitHub Issue Search演示

有了这些新功能，我们很兴奋地增强了我们的GitHub Issue Search演示。由于Manticore的用户友好设计，集成模糊搜索和自动补全功能非常简单。

要启用模糊搜索，我们只需在搜索查询中包含[这些行](https://github.com/manticoresoftware/manticore-github-issue-search/blob/a62a0248da47d70ee395283a1127d0c7a51aa91a/app/src/lib/Manticore.php#L863-L875)：

```php
$search->option('fuzzy', 1);
$search->option('layouts', ['ru', 'us', 'ua']);
```

对于查询建议，我们利用了[新自动补全](https://github.com/manticoresoftware/manticore-github-issue-search/blob/a62a0248da47d70ee395283a1127d0c7a51aa91a/app/src/lib/Manticore.php#L399-L428)功能：

```php
$result = $client->autocomplete([
    'body' => [
        'table' => $table,
        'query' => $query,
        'options' => [
            'fuzziness' => 1,
            'layouts' => ['ru', 'ua', 'us'],
        ],
    ],
]);
```

这些增强功能显著改进了我们演示中的搜索功能，为用户提供更精确的结果和有用的建议。

## GitHub Issue Search演示中的效果

通过Manticore Search将自动补全和模糊搜索与键盘布局猜测集成，改善了用户与搜索工具的交互方式。通过利用模糊性进行搜索并根据输入模式提供建议，用户可以快速找到相关结果。

以下是自动补全功能的运行方式，模仿流行的搜索建议界面：

![自动补全展示](./new-fuzzy-search-and-autocomplete/autocomplete-showcase.png)

此外，模糊搜索通过解决常见的问题（如拼写错误）来增强用户交互。如果有人搜索产品但拼写错误，模糊搜索确保他们仍能获得相关结果。这是GitHub Issue Search演示中的效果：

![模糊搜索展示](./new-fuzzy-search-and-autocomplete/fuzzy-search-showcase.png)

## 结论

通过将**模糊搜索**和**查询建议**集成到Manticore Search中，我们大大增强了其功能。这些功能使搜索更加直观、宽容和高效。

我们鼓励您在我们的[GitHub Issue Search演示](https://github.manticoresearch.com)中尝试这些新功能并分享您的反馈。您的见解对我们继续改进和扩展Manticore Search的功能至关重要。

敬请期待更多更新，并且如果您认为该项目有用，请考虑给我们[GitHub仓库](https://github.com/manticoresoftware/manticore-github-issue-search)点个星标！

---
