使用 Meili 搜索 Rust 包
Meili 即时搜索引擎的演示,该引擎展示了 crates.io 中的包。
今天,我将带您深入了解 crates.io,以及如何使用我们的即时搜索引擎:Meilisearch,制作了一个替代搜索栏。
Meili 即时、相关且容错的搜索引擎
Crates.io 是存储 Rust 社区包(packages)的官方网站,也是 cargo 包管理器上传、更新和下载这些包的地方。
Sean Griffin 是 crates.io 团队的一员,负责维护其当前的搜索引擎以及整个网站。Kornel Lesinski 构建了 lib.rs,它是 crates.io 的替代品,并使用 Tantivy 来驱动其搜索栏。老实说,我更喜欢它的颜色设计,这就是我将其用于我们的搜索演示的原因。
我决定运行我们的即时搜索引擎,并测试其随着时间的推移与现有解决方案的相关性。我们的搜索引擎使用完全不同的算法;它基于前缀搜索并且具有容错性。
Meili 具有容错性并支持许多其他功能
所以,我问自己:为什么不使用我们新的即时搜索引擎,并使其对我们心爱的社区有用呢?这会在过程中给我们很多反馈,并且可能有一些拉取请求。
在 Meili,我们管理一个内部 Kubernetes 集群,这对于为客户托管演示非常有用。此演示的 Meilisearch 服务器目前在此集群中的一个 pod 中运行。
为了让 Meilisearch 展示这些包,我们需要找到 crates.io 上所有当前可用的包。幸运的是,此索引以多个子文件夹的形式在 GitHub 上可用,其中包含包的名称和版本,其中包含大约 32 000 个文件。每次将包更新到新版本或版本被撤回时,都会进行提交。
因此,我使用了 crates.io-index 存储库来初始化我们新创建的 Meili 搜索引擎,但首先需要更多数据,例如每个包的描述、关键字和类别。同样,Rust crates.io 团队在这里为我们提供了帮助,我与 Pietro Albini 交谈,他指出了向我们提供包内容的不限速服务器。
现在我们可以检索有用的数据,我创建了一个 异步爬虫,该爬虫下载、提取、检索 Cargo.toml,并将基本数据上传到 Meilisearch。
Meili 仪表板界面显示原始文档
Meilisearch 现在理解了这些数据,并为我们提供了即时、相关且容错的响应。但是,新包呢?我们希望收到有关新包的通知,并能够将其发送到 Meilisearch。
Docs.rs 是官方网站,用于计算和存储由 crates.io 托管的所有 Rust 包的文档。它每分钟都会对 crates.io 索引进行差异比较,以了解有关新包更新的信息。幸运的是,它提供了这些更新的 Atom Feed。
这就是 Heroku 发挥作用的地方。Heroku 在其服务器上每月提供大约 1000 个免费计算小时,并为我们提供调度程序。我们可以消耗这些积分,并通过获取 Atom Feed,下载更新的包(如之前一样),并最终实时更新我们的搜索引擎,每 10 分钟自由询问 docs.rs 有关新更新的包!
获取新包需要 4 秒钟
搜索结果令人满意,但不如预期,有些地方不对。例如,当我们写“serde”时,第一个结果是相关的,但接下来的结果不是。这与 Meilisearch 没有足够的数据来评估包(除了查询匹配的单词)有关。
Meilisearch 不知道如何仅通过匹配的单词来确定相同包
下载次数显著提高了搜索结果。此数据可通过 crates.io 获取。每天都会进行完整的数据库导出,其中包含每个包的下载次数。我决定将这些作为最后的排名标准,以帮助 Meilisearch 确定被视为相等的包。
由于下载次数,Meilisearch 显示更好的结果
我部署了一个 Heroku 调度程序,每天运行一次,以更新所有包的下载次数;下载 tarball、解压缩、读取 CSV 并将 32 000 个包的下载次数上传到 Meilisearch 大约需要 30 秒钟。因此,我们远未达到每月 1000 个免费小时。
我认为这个搜索演示非常好,但我也考虑添加同义词和停用词,因为 Meilisearch 支持这些。例如,如果能写“db”并看到与“database”相关的结果会很不错。停用词将有助于忽略像“the”或“that”这样的无用词,这些词有时会污染搜索结果,但我们需要小心,因为包的名称可能由停用词组成。
Meilisearch 还支持基本筛选,并且将来能够搜索特定类别或具有特定关键字的包会很棒。
所有这些改进都可以由您完成;该演示是开源的。核心引擎源代码也可在 GitHub 上找到,这就是本文的重点!请看一下并谈论它,更多人参与,更多功能!