当前位置:首页 > Rust > 正文

使用 Rust 构建高效全文搜索引擎(tantivy 入门实战教程)

在当今信息爆炸的时代,快速、准确地检索文本数据变得尤为重要。如果你正在使用 Rust 编程语言,并希望为你的项目添加强大的搜索功能,那么 tantivy 将是一个绝佳的选择。本文将带你从零开始,手把手教你如何使用 tantivy 构建一个简单的 Rust全文搜索引擎,即使你是编程新手也能轻松上手。

什么是 tantivy?

tantivy 是一个用 Rust 编写的高性能、全文本搜索引擎库,灵感来源于 Apache Lucene。它支持倒排索引、分词、布尔查询、短语匹配、相关性排序等功能,非常适合用于构建本地或嵌入式搜索系统。由于其基于 Rust 的内存安全和并发特性,tantivy 在性能和稳定性方面表现优异。

使用 Rust 构建高效全文搜索引擎(tantivy 入门实战教程) Rust全文搜索引擎 tantivy教程 Rust搜索引擎库 构建搜索引擎 第1张

准备工作:安装依赖

首先,确保你已安装 Rust 工具链(包括 cargo)。如果尚未安装,请访问 Rust 官网 进行安装。

接下来,在你的项目目录中初始化一个新的 Rust 项目:

cargo new tantivy_democd tantivy_demo

然后,在 Cargo.toml 文件中添加 tantivy 依赖:

[dependencies]tantivy = "0.22"

步骤一:定义索引结构

在 tantivy 中,你需要先定义“Schema”(索引结构),告诉搜索引擎哪些字段需要被索引、是否存储原始值、是否分词等。

打开 src/main.rs,写入以下代码:

use tantivy::schema::*;use tantivy::{doc, Index, IndexWriter, QueryParser, ReloadPolicy};use std::path::Path;fn main() -> tantivy::Result<()> {    // 1. 创建 Schema    let mut schema_builder = Schema::builder();    let title = schema_builder.add_text_field("title", TEXT | STORED);    let body = schema_builder.add_text_field("body", TEXT | STORED);    let schema = schema_builder.build();    // 2. 创建索引(内存索引)    let index = Index::create_in_ram(schema.clone());    // 后续步骤...    Ok(())}

这里我们定义了两个字段:titlebody,都启用了 TEXT(表示要分词并建立倒排索引)和 STORED(表示原始内容会被保存,可用于展示结果)。

步骤二:添加文档到索引

现在我们向索引中添加一些示例文档:

    // 3. 获取索引写入器    let mut index_writer: IndexWriter = index.writer(50_000_000)?;    // 4. 添加文档    index_writer.add_document(doc!(        title => "Rust 编程入门",        body => "Rust 是一种系统编程语言,注重安全性和并发性。"    ));    index_writer.add_document(doc!(        title => "tantivy 使用指南",        body => "tantivy 是 Rust 实现的全文搜索引擎,性能卓越。"    ));    index_writer.add_document(doc!(        title => "构建搜索引擎",        body => "使用 tantivy 可以轻松构建本地全文搜索引擎。"    ));    // 提交更改    index_writer.commit()?;

步骤三:执行搜索查询

添加完文档后,我们可以使用 QueryParser 来解析用户输入并执行搜索:

    // 5. 创建搜索器    let reader = index.reader()?;    let searcher = reader.searcher();    // 6. 解析查询(在 title 和 body 字段中搜索)    let query_parser = QueryParser::for_index(&index, vec![title, body]);    let query = query_parser.parse_query("Rust")?;    // 7. 执行搜索,最多返回 10 条结果    let top_docs = searcher.search(&query, &tantivy::collector::TopDocs::with_limit(10))?;    // 8. 打印结果    for (_score, doc_address) in top_docs {        let retrieved_doc = searcher.doc(doc_address)?;        println!("Title: {}", retrieved_doc.get_first(title).unwrap().text().unwrap());        println!("Body: {}\n", retrieved_doc.get_first(body).unwrap().text().unwrap());    }    Ok(())

完整代码整合

将上述所有代码整合后,main.rs 应如下所示:

use tantivy::schema::*;use tantivy::{doc, Index, IndexWriter, QueryParser};fn main() -> tantivy::Result<()> {    let mut schema_builder = Schema::builder();    let title = schema_builder.add_text_field("title", TEXT | STORED);    let body = schema_builder.add_text_field("body", TEXT | STORED);    let schema = schema_builder.build();    let index = Index::create_in_ram(schema.clone());    let mut index_writer = index.writer(50_000_000)?;    index_writer.add_document(doc!(        title => "Rust 编程入门",        body => "Rust 是一种系统编程语言,注重安全性和并发性。"    ));    index_writer.add_document(doc!(        title => "tantivy 使用指南",        body => "tantivy 是 Rust 实现的全文搜索引擎,性能卓越。"    ));    index_writer.add_document(doc!(        title => "构建搜索引擎",        body => "使用 tantivy 可以轻松构建本地全文搜索引擎。"    ));    index_writer.commit()?;    let reader = index.reader()?;    let searcher = reader.searcher();    let query_parser = QueryParser::for_index(&index, vec![title, body]);    let query = query_parser.parse_query("Rust")?;    let top_docs = searcher.search(&query, &tantivy::collector::TopDocs::with_limit(10))?;    for (_score, doc_address) in top_docs {        let retrieved_doc = searcher.doc(doc_address)?;        println!("Title: {}", retrieved_doc.get_first(title).unwrap().text().unwrap());        println!("Body: {}\n", retrieved_doc.get_first(body).unwrap().text().unwrap());    }    Ok(())}

运行程序

在终端中执行:

cargo run

你应该会看到类似如下的输出:

Title: Rust 编程入门Body: Rust 是一种系统编程语言,注重安全性和并发性。

进阶建议

以上只是一个最基础的示例。在实际项目中,你可能需要:

  • 将索引持久化到磁盘(使用 Index::create 而非 create_in_ram
  • 自定义中文分词器(tantivy 默认使用英文分词)
  • 支持高亮、过滤、排序等高级功能
  • 集成 Web 框架(如 Actix 或 Rocket)提供 API 接口

结语

通过本教程,你已经掌握了如何使用 tantivy 这个强大的 Rust搜索引擎库 来构建一个简单的全文检索系统。无论你是想为个人项目添加搜索功能,还是深入研究搜索引擎原理,tantivy 都是一个值得信赖的工具。希望这篇 tantivy教程 能帮助你迈出构建 Rust全文搜索引擎 的第一步!

Happy Coding with Rust and tantivy! 🦀🔍