TL;DR: 在这篇博客中,我们展示了如何制作一个与 GitHub 用于查找问题的搜索应用非常相似的应用,使用 Manticore Search。
- 尝试一下演示:
- 爬取你的仓库 - https://github.manticoresearch.com/ 。你需要等待。
- 在爬取的仓库中搜索 - https://github.manticoresearch.com/manticoresoftware/manticoresearch 。
- GitHub 项目 - https://github.com/manticoresoftware/manticore-github-issue-search 。
- 为自己设置 ,以新的方式查看你的 GitHub 问题、拉取请求和评论。
介绍
在我们有效展示 Manticore Search 的能力和性能的旅程中,我们意识到选择一个可以作为有说服力展示的真实应用的重要性。我们考虑了几个选项——常见的选择如:
- 电子商务网站
- 目录列表
- 电影数据库等。
虽然这些是熟悉且易于理解的例子,Manticore 也非常适合它们,但它们在提供实际价值方面有所欠缺。
就在这时灵感闪现:为什么不为 GitHub 问题创建一个搜索工具呢? 这不仅给了我们提供强大演示的机会,还为我们提供了利用 Manticore Search 的高级功能来增强搜索体验的机会,这至少对我们 Manticore 核心团队是有用的。
我们接受了这个挑战,并自豪地呈现我们的创作——一个专门为 GitHub 问题量身定制的搜索引擎。这不仅仅是一个演示;它是一个实用工具,我们希望它能对 GitHub 社区大有裨益。
我们邀请你探索并与我们的 GitHub 问题搜索互动,网址是 https://github.manticoresearch.com 。通过这个动手体验,发现 Manticore Search 的全部潜力。享受我们增强的搜索能力,亲自体验 Manticore Search 如何改变数据探索。
在某些情况下,我们的搜索速度比 GitHub 快了多达 30 倍。想知道它是如何工作的以及我们是如何做到的吗?让我们深入了解我们是如何构建它的。
| GitHub 搜索 - 215 ms | 通过 Manticore 的 GitHub 搜索 - 6 ms |
|---|---|
![]() | ![]() |
先决条件
这个概念很简单——我们的目标是将选定的 GitHub 仓库中的数据提取到 Manticore 搜索数据库中。通过对数据进行全文索引,我们可以启用有效的搜索功能。
我们的决定是保持一个与 GitHub 非常相似的设计,但在用户界面上进行微妙的增强,以适应不仅是技术精湛的用户,还有那些技术知识较少的用户。
此外,我们还旨在引入额外的功能,例如:
- 跨问题和评论的组合搜索
- 高级过滤选项
- 根据反应排序结果的能力
- 无限滚动分页
让我们深入细节,检查面临的挑战,并探索 Manticore 如何通过一个实际示例来解决这些问题。
为 MVP 选择合适的工具
开发一个演示可能是相当具有挑战性的,但当你与时间赛跑时,你需要尽可能多的帮助。这正是我们依赖于经过验证的 PHP 后端和 JavaScript 客户端组合的原因——再加上一点 SEO 友好的混合魔法。你问为什么选择 PHP?嗯,这就像给你的项目背上装上了喷气背包!它启动迅速,验证简单,测试轻松。而且,当然,因为我们的团队在 PHP 方面的经验比在其他美丽而现代的编程语言上要多。(顺便说一下, 阅读关于 如何为用 C++ 编写的 Manticore Search 构建 PHP 插件。)
Manticore Search 还配备了 PHP 客户端 ,我们在演示中使用它。使用它就像下面这样简单:
<?php
use Manticoresearch\\Client;
$client = new Client(['host' => 'localhost', 'port' => 9308]);
$index = $client->index('repo');
$docs = $index->search('bug')->get();
foreach ($docs as $doc) {
var_dump($doc->getId(), $doc->getData());
}
就这样,你创建了一个 Manticore 客户端,选择你想要交互的表,发送搜索请求,然后——瞧!——结果源源而来。
我们不会在这里深入探讨 Manticore Search PHP 客户端,但如果你渴望尝试一下,可以查看他们的仓库 Manticore Search PHP Client 。
演示包含多个组件,因为它:
- 从 GitHub 获取数据,
- 维护一个待处理的仓库队列
- 可以通过电子邮件发送通知
- 等等等等
为了方便你,所有与 Manticore Search 交互的代码都位于 Manticore.php 。这对任何考虑将来比较不同存储引擎的人也可能有用。
我们必须克服的有趣挑战
在开发演示的过程中,除了实现上述琐碎的事情外,我们还遇到了一些有趣的挑战,你在项目中也可能会遇到。
结合两个表时搜索结果的相关性
任何搜索系统的一个关键方面是其结果的相关性。当使用 Manticore Search 作为后端实现 GitHub 问题演示时,值得注意的是,相关性在开箱即用的情况下得到了有效管理。Manticore Search 采用经典的基于 BM25 的排名方法,根据文档和查询中关键词的频率和重要性以及字段长度归一化(匹配术语所在文本字段的长度)对搜索结果进行排序。这意味着无需复杂的配置或复杂的算法即可开始高效的搜索体验。有关更多详细信息,请参阅文档 – 排名概述 。
我们面临的挑战涉及在 GitHub 问题和评论中执行组合搜索。从技术上讲,我们在 Manticore 层将其分为两个独立的表:一个用于问题,另一个用于评论。在研究排名机制后,我们决定实现 Rank-Biased Precision (RBP) 算法,这使我们能够合并来自两个不同来源的结果。此外,Manticore Search 提供了一个可以通过 PHP 客户端的 $doc->getScore() 方法检索的 'score' 字段。您可以在此处查看代码:
Manticore.php 代码
。
因此,我们不仅实现了“开箱即用”的相关性,还利用 RBP 来结合两个来源,最大化搜索结果的有效性!
问题和评论的高级过滤

步骤 1:渲染范围
在搜索功能的领域中,单纯的基本搜索往往不足以满足需求。用户经常需要使用过滤器来细化他们的结果。在 Manticore Search 和许多其他搜索引擎中,实现基于范围或相等的简单过滤器是直接的。然而,当涉及在某些范围内对结果进行分组时,这项任务可能看起来令人生畏——但实际上,使用 Manticore Search 这非常可管理。
我们的目标是使用户能够选择预定义的范围并相应地应用过滤器,同时避免存储或缓存任何额外数据。例如,我们旨在按评论数量过滤问题:≤ 5,介于 5 和 10 之间,以及 ≥ 10。Manticore Search 通过其 INTERVAL 函数简化了此过程。让我们看看它在演示中的实现。
我们设计了一种特殊的方法,生成我们所需的范围以及每个范围内项目的计数。以下是伪代码,以便理解它是多么简单:
$client = static::client();
$index = $client->index('issue');
$search = $index->search('');
$range = implode(',', $values);
$facets = $search
->limit(0)
->filter('repo_id', $repoId)
->expression('range', "INTERVAL(comments, $range)")
->facet('range', 'counters', sizeof($values) + 1)
->get()
->getFacets();
您可以在以下 URL 查看完整代码:
步骤 2:应用过滤器
下一步涉及过滤结果。这是通过使用 gt(大于)过滤器结合 or 条件来实现的。以下是代码的简化表示:
$search->filter('comments', 'gt', 0, Search::FILTER_AND);
$search->filter('comments', 'lte', 3, Search::FILTER_OR);
您可以通过此链接检查我们的代码片段:
按反应排序
在 GitHub 上进行搜索时,您可能会注意到它不显示或允许按反应进行过滤。然而,有时识别反应最多的问题可能特别有洞察力——例如,评估最受欢迎的功能或预测即将出现的问题。这就是按反应排序变得无价的地方。
首先,我们需要捕获反应数据。GitHub API 方便地以简单的 JSON 对象形式提供了这些数据:
{
"url": "https://api.github.com/repos/ClickHouse/ClickHouse/issues/35407/reactions",
"total_count": 0,
"+1": 0,
"-1": 0,
"laugh": 0,
"hooray": 0,
"confused": 0,
"heart": 0,
"rocket": 0,
"eyes": 0
}
这是个好消息,因为 Manticore Search 提供了 原生 JSON 支持 !
接下来,我们必须考虑排序的需求。我们需要按单个 JSON 字段排序还是按多个字段的总和排序?幸运的是,Manticore Search 使我们能够同时做到这两点。它完全符合我们的需求!我们可以直接将 JSON 存储在表中,并使用以下代码片段来启用排序:
$search->expression(
'positive_reactions',
'integer(reactions.`+1`) + integer(reactions.hooray) + integer(reactions.heart) + integer(reactions.rocket)'
);
有关排序实现的全面视图,请参阅此处的完整代码片段: Manticore PHP 客户端排序示例
如上所示,我们利用 Manticore PHP 客户端的 expression 函数使用 . 符号访问 JSON 字段。这种方法消除了缓存计数器或执行额外计算的需要。您可以创建一个 JSON 字段,使用表达式访问它,保持高速,并避免缓存机制的开销!
分面搜索
搜索和过滤能力是任何强大搜索功能的基本组成部分。然而,在获取计数的速度方面常常会出现挑战。众所周知,在 MySQL 中实现快速计数操作需要使用索引。这些索引不仅会扩大数据库的大小,还会增加对负载较重的应用程序的复杂性,这些应用程序通常会诉诸于缓存,并随后根据需要调整这些计数。
好消息是,Manticore Search 完全避免了这些问题!使用 Manticore Search,从数据库中检索计数既简单又快速,消除了对额外缓存层的需求。
为了显示反映页面上应用的过滤器的实时计数,我们利用与搜索相同的过滤器。然而,我们引入了一个额外的查询用于面,耗时仅几毫秒。这种方法使我们能够以几乎没有开销的方式获取指定组的当前计数。下面是一个简洁的 PHP 代码片段,演示如何实现这一点:
$facets = $search
->limit(0) // We're only interested in counts, hence no results needed
->filter('repo_id', $repoId) // Filter by repository ID
->expression('open', 'if(closed_at=0,1,0)') // Evaluate whether issues are open
->facet('open', 'counters', 2) // Get facet counts for open and closed issues
->get() // Execute the search query and retrieve the results
->getFacets(); // Extract the facets data from the results
让我们分解一下:我们将限制设置为零,因为我们的目标是获取计数器,而不是搜索结果。我们按存储库 ID 进行过滤,并应用一个表达式按 closed_at 字段进行分组。这个分组为我们提供了开放和关闭问题的计数器。
对于那些对完整实现感兴趣的人,完整的代码片段可以在 GitHub 上找到: Manticore GitHub Issue Search - Manticore.php
使用 Manticore Search,获取计数的挑战几乎通过开箱即用的解决方案得以解决。还有什么比这更高效和用户友好的呢?😊
结论和进一步计划
在开发我们的演示项目的过程中,我们旨在展示 Manticore Search 的能力和效率。结果不仅达到了我们的预期,还为我们提供了一种增强我们导航 GitHub 存储库方式的工具。通过这一举措,我们能够展示 Manticore Search 的潜力,并整合了一些改进和功能,增强了 GitHub 上的当前产品:
- 我们实现了明显更快的搜索速度,搜索通常在约 5-10 毫秒内完成,而 GitHub 的搜索时间超过 200 毫秒。
- 我们的演示项目允许在搜索结果中包含评论,提供比 GitHub 当前可用信息更广泛的范围。
- 我们引入了用户根据反应数量对问题进行排序的功能,提供了用户交互的额外维度。
- 提供了高级过滤选项,允许更精确的搜索,例如显示特定评论范围内的问题或专注于仅在评论中进行搜索。
我们鼓励您通过访问以下链接来探索这些增强功能: https://github.manticoresearch.com
此外,对于那些对开源代码或在本地运行项目感兴趣的人,可以在这里访问: https://github.com/manticoresoftware/manticore-github-issue-search
我们还很高兴地宣布计划将 向量搜索 (在 Manticore 开发包中可用,准备发布)纳入我们的演示中。这个即将推出的功能旨在进一步提高结果的质量,当与全文搜索结合时,展示如何利用 Manticore 中的新功能来增强搜索功能,因此请保持关注并 在 Twitter 上关注我们 。
我们欢迎您对 Manticore Search 的功能和能力的这一实际演示提供反馈,并期待与您分享更多更新。期待您的反馈: issues , discussions 。


