Tantivy使用Rust 开发的全文搜索引擎库

news2025/1/11 22:47:04

一、概述

Tantivy是一个全文搜索引擎库,灵感来自Apache Lucene,用Rust编写。
在这里插入图片描述

如果你正在寻找Elasticsearch或Apache Solr的替代品,请查看我们基于Tantivy构建的分布式搜索引擎Quiuckwit。

Tantivy更接近Apache Lucene,而不是Elasticsearch或Apache Solr,因为它不是现成的搜索引擎服务器,而是一个可用于构建此类搜索引擎的库。

Tantivy的性能非常棒,请看下图:
在这里插入图片描述

二、特征

  • 全文搜索
  • 可配置的标记器(可用于 17种拉丁语言的词干提取),并支持第三方对中文(tantivy-jieba和cang-jie)、日语(lindera、Vaporetto和tantivy-tokenizer-tiny-segmenter)和韩语(lindera+ lindera-ko-dic-builder)的支持
  • 快速(查看🐎 ✨基准✨ 🐎)
  • 启动时间极短 (<10ms),非常适合命令行工具
  • BM25 评分(与 Lucene 相同)
  • 自然查询语言(例如(michael AND jackson) OR “king of pop”)
  • 短语查询搜索(例如"michael jackson")
  • 增量索引
  • 多线程索引(在我的桌面上索引英文维基百科只需不到 3 分钟)
  • Mmap 目录
  • 当平台/CPU 包含 SSE2 指令集时,SIMD 整数压缩
  • 单值和多值 u64、i64 和 f64 快速字段(相当于 Lucene 中的 doc 值)
  • &[u8]快速场
  • 文本、i64、u64、f64、日期、ip、bool 和分层方面字段
  • 压缩文档存储(LZ4、Zstd、None)
  • 范围查询
  • 分面搜索
  • 可配置索引(可选词频和位置索引)
  • JSON 字段
  • 聚合收集器:直方图、范围桶、平均值和统计指标
  • 带删除的 LogMergePolicy
  • 搜索器预热 API
  • 带有马的俗气标志

注意:分布式搜索超出了 Tantivy 的范围,但如果您正在寻找此功能,请查看Quickwit。

三、Tanvity的小示例


use tantivy::collector::TopDocs;
use tantivy::query::QueryParser;
use tantivy::schema::*;
use tantivy::{doc, Index, IndexWriter, ReloadPolicy};
use tempfile::TempDir;

fn main() -> tantivy::Result<()> {
 let index_path = TempDir::new()?;
 let mut schema_builder = Schema::builder();
 schema_builder.add_text_field("title", TEXT | STORED);
 schema_builder.add_text_field("body", TEXT);
 let schema = schema_builder.build();
 let index = Index::create_in_dir(&index_path, schema.clone())?;
 let mut index_writer: IndexWriter = index.writer(50_000_000)?;
 let title = schema.get_field("title").unwrap();
    let body = schema.get_field("body").unwrap();

    let mut old_man_doc = TantivyDocument::default();
    old_man_doc.add_text(title, "The Old Man and the Sea");
    old_man_doc.add_text(
        body,
        "He was an old man who fished alone in a skiff in the Gulf Stream and he had gone \
         eighty-four days now without taking a fish.",
    );
  
   index_writer.add_document(old_man_doc)?;
   index_writer.add_document(doc!(
    title => "Of Mice and Men",
    body => "A few miles south of Soledad, the Salinas River drops in close to the hillside \
            bank and runs deep and green. The water is warm too, for it has slipped twinkling \
            over the yellow sands in the sunlight before reaching the narrow pool. On one \
            side of the river the golden foothill slopes curve up to the strong and rocky \
            Gabilan Mountains, but on the valley side the water is lined with trees—willows \
            fresh and green with every spring, carrying in their lower leaf junctures the \
            debris of the winter’s flooding; and sycamores with mottled, white, recumbent \
            limbs and branches that arch over the pool"
    ))?;
      index_writer.add_document(doc!(
    title => "Frankenstein",
    title => "The Modern Prometheus",
    body => "You will rejoice to hear that no disaster has accompanied the commencement of an \
             enterprise which you have regarded with such evil forebodings.  I arrived here \
             yesterday, and my first task is to assure my dear sister of my welfare and \
             increasing confidence in the success of my undertaking."
    ))?;
     index_writer.commit()?;
         let reader = index
        .reader_builder()
        .reload_policy(ReloadPolicy::OnCommitWithDelay)
        .try_into()?;
     let searcher = reader.searcher();
     let query_parser = QueryParser::for_index(&index, vec![title, body]);
     let query = query_parser.parse_query("sea whale")?;
     let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?;
      for (_score, doc_address) in top_docs {
        let retrieved_doc: TantivyDocument = searcher.doc(doc_address)?;
        println!("{}", retrieved_doc.to_json(&schema));
    }
      let query = query_parser.parse_query("title:sea^20 body:whale^70")?;

    let (_score, doc_address) = searcher
        .search(&query, &TopDocs::with_limit(1))?
        .into_iter()
        .next()
        .unwrap();

    let explanation = query.explain(&searcher, doc_address)?;

    println!("{}", explanation.to_pretty_json());

    Ok(())
}

Github: https://github.com/quickwit-oss/tantivy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1959685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

仅需一分钟,使用极空间部署一个强大的开源问卷考试系统『SurveyKing』

仅需一分钟&#xff0c;使用极空间部署一个强大的开源问卷考试系统『SurveyKing』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 我们生活中估计应该都收到了不少的问卷调查吧&#xff1f;很多商家或者运营商都会通过问卷调查的方式了解客户满意度&#xff0c;或者高市场调研&…

数据中台建设之数据汇聚与数据交换

目录 一、数据汇聚 1.1 概述 1.2 汇聚数据类型 1.2.1 结构化数据 1.2.2 半结构化数据 1.2.3 非结构化数据 1.3 汇聚数据模式 1.3.1 概述 1.3.2 离线 1.3.3 实时 1.4 汇聚数据方法 1.4.1 概述 1.4.2 ETL 1.4.3 ELT 1.5 汇聚数据工具 1.5.1 概述 1.5.2 Flink CDC…

Java人力资源招聘社会校招类型招聘系统PC端

&#x1f50d;【揭秘】人力资源新利器&#xff01;社会校招一站式PC端招聘系统全攻略&#x1f680; &#x1f308; 开篇引言&#xff1a;招聘新纪元&#xff0c;效率为王&#xff01; Hey小伙伴们&#xff0c;你是否还在为繁琐的招聘流程头疼不已&#xff1f;&#x1f92f; 面…

Spark累加器(Accumulator)

1.累加器类型&#xff1a; 数值累加器&#xff1a;用于计算总和、计数等。布尔累加器&#xff1a;用于计算满足特定条件的次数。自定义累加器&#xff1a;允许定义复杂的聚合逻辑和数据结构。集合累加器&#xff1a;用于计算唯一元素的数量&#xff0c;处理去重操作。 在 Spar…

Qt Designer,仿作一个ui界面的练习(四):编写代码

一、新建项目&#xff0c;目录结构如图&#xff1a; PYS下存放脚本&#xff0c;SRC下存放资源文件&#xff0c;UIS下存放组态画面文件。 在每个子目录下都有__init__.py文件&#xff0c;系统会自动将其识别为软件包。 其中一个UIS.__init__.py文件的内容&#xff1a; # impo…

手撕数据结构02--二分搜索(附源码)

一、理论基础 二分搜索&#xff0c;也称折半搜索、对数搜索&#xff0c;是一种在有序数组中查找某一特定元素的搜索算法。 二分搜索是一种高效的查找算法&#xff0c;适用于在已排序的数组中查找特定元素。它的基本思想是通过不断将搜索区间对半分割&#xff0c;从而快速缩小…

ROOM数据快速入门

ROOM数据库快速入门 文章目录 ROOM数据库快速入门第一章 准备工作第01节 引入库第02节 布局文件第03节 activity类第04节 效果图 第二章 数据类第01节 实体类&#xff08;表&#xff09;第02节 数据访问类&#xff08;DAO&#xff09;第03节 数据Service层第04节 RoomDataBase …

达梦数据库DPI 实现两个数据库数据互通

链接字符串是目标访问链接 目标访问用户名 口令实现 31 里访问33库的数据 如果在31上建立视图访问33的某个表 AS SELECT SZZJ.sys_user.id FROM SZZJ.sys_userszzj31_szzj33;

护眼灯哪些牌子好?五款专业护眼灯品牌排行推荐

普通台灯长时间使用下来&#xff0c;眼睛疲劳、酸涩。但当作业或者工作没有做完的时候&#xff0c;还得硬着头皮撑着。大家是不是经常为这种事情发愁&#xff1f;于是&#xff0c;护眼台灯被设计出来了&#xff0c;但市面上出现的护眼台灯种类多&#xff0c;质量也是难以保证&a…

开发进度网站带后台源码

【源码介绍】 后台地址是&#xff1a;admin.php 后台没有账号密码 这个没有数据库 有能力的可以自己改 【搭建教程】 1.源码上传至虚拟机或者服务器 2.绑定域名和目录 3.访问域名安装&#xff0c; 4.安装完成后就行了 注&#xff1a;资源均网络搬运 仅供测试学习使用&#xff…

【数据结构与算法】队列(顺序存储)

队列 一.队列的原理二.队列的结构三.队列初始化四.判断队列是否满或空1.是否为满2.是否为空 五.入队操作六.队列的遍历七.出队操作1.前移2.后指 八.其他小接口1.获取队列首元素2.获取队列长度3.清除队列 酒.总结 一.队列的原理 队列也是一种线性结构,只不过是一种受限制的线性…

微服务面试-分布式 注册中心 远程调用 保护

标红的原理还是不太熟悉 重新看 分布式事务 CAP理论 Consistency&#xff08;一致性&#xff09; Availability&#xff08;可用性&#xff09; Partition tolerance &#xff08;分区容错性&#xff09; BASE 理论 就是做取舍 cap三选二 AT模式脏写 TCC模式 注册中…

25考研数据结构复习·6.4图的应用

最小生成树 Prim算法 从某一顶点开始构建生成树&#xff1b;每次将代价最小的新顶点纳入生成树&#xff0c;知道所有顶点都纳入为止。 时间复杂度O(|V|^2) 适合用于边稠密图 实现思想 从V0开始&#xff0c;总共需要n-1轮处理 每一轮处理&#xff1a;循环遍历所有结点&…

京东商品详情API:多规格商品的返回值处理

处理京东商品详情API中关于多规格商品的返回值&#xff0c;首先需要了解京东API的返回数据结构。通常&#xff0c;对于多规格商品&#xff08;如不同颜色、尺寸等选项的商品&#xff09;&#xff0c;API会返回一个包含多个规格选项和对应价格、库存等信息的复杂数据结构。 以下…

java中 VO DTO BO PO DAO

VO、DTO、BO、PO、DO、POJO 数据模型的理解和实际使用_vo dto bo-CSDN博客 深入理解Java Web开发中的PO、VO、DTO、DAO和BO概念_java dto dao-CSDN博客

汇凯金业:区块链的介绍和应用场景

区块链&#xff0c; 一个近年来炙手可热的技术名词&#xff0c; 它就像一颗耀眼的明星&#xff0c; 吸引着人们的目光&#xff0c; 引发着人们的思考。 究竟什么是区块链? 它为何能够引发如此巨大的关注? 它又将如何改变我们的未来? 一、 区块链&#xff1a; 去中心化的信任…

中仕公考:什么是事业编?

事业编制内的职员是指那些经过考试选拔&#xff0c;成功进入公共机构服务&#xff0c;同时在人事部门和组织部有正规记录的个体。 入职条件&#xff1a; 要求应聘者参与由事业单位举办的公开招聘考试。 管理方式&#xff1a; 事业编制内职员的人事管理由当地的人事部门或相…

02 RabbitMQ:下载安装

02 RabbitMQ&#xff1a;下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…

Windows API钩子

原文链接&#xff1a;https://www.cnblogs.com/zhaotianff/p/18073138 有前面的文章中&#xff0c;我介绍了一个Windows API的监控工具&#xff08;API Monitor&#xff09;的使用。它内部就是使用了Hook机制&#xff0c;能Hook Windows API&#xff0c;能在我们钩选的API函数…

C++必备知识--类和对象

类的定义 格式 class是类的关键字&#xff0c;Stack是类的名字(自己定义的)&#xff0c;在{}中定义类的主体。C中类的出现是为了替代C语言中的结构体&#xff0c;所以类的结构与结构体类似&#xff0c;{}之后需要加分号。类体中的内容称为类的成员&#xff0c;类中(声明)的变量…