Electron 集成SQlite FTS5 实现百万级数据的倒排索引

news2025/4/17 7:04:12

背景

  1. 在产品迭代时,个人版产品已经将联系人和消息实时备份到本地,而消息的备份的目的仍然是为了快速查询对自己有用的上下文,并能快速定位到这些用户以及这些有用的信息。另外包括未来喂给 chatgpt-4o 的数据也是需要调用搜索获取的,也不是全量喂,以减少无用信息的资源浪费。

  2. 关系型数据库建立的是 B 树索引,而全文索引采用的是文本倒排索引,前者是正排查询,在处理文字间隔情况下,几乎是白痴级遍历和比对,后者却是利用词根的方式反差文档 ID,效率上高了太多倍。

SQLite 自带全文倒排索引

咨询 ChatGPT 询问是否有轻量级可以在客户端上使用的倒排索引库,ChatGPT 推荐了 SQLite FTS5,实际测试效果还不错。

实际使用的 SQL 语句,明显发现对中文的检索支持比较差

CREATE VIRTUAL TABLE documents USING fts5(title, body);

INSERT INTO documents (title, body) VALUES ('Twelfth-Night', 'If music be the food of love, play on: Give me excess of it…');
INSERT INTO documents (title, body) VALUES ('Macbeth', 'When shall we three meet again In thunder, lightning, or in rain?');
INSERT INTO documents (title, body) VALUES ('zhengxi', '😇🤣😆#;;郑钦文已于当地时间5日早上离开巴黎,备战北美赛季,这也意味着郑钦文无缘本次巴黎奥运会的中国代表团闭幕式的旗手.');
INSERT INTO documents (title, body) VALUES ('eluosi','Он очень прост в использовании, поддерживается загрузка как в Excel, так и в CSV, и в основном он бесплатен.');
INSERT INTO documents (title, body) VALUES ('email', 'leiluo88888888@gmail.com');
INSERT INTO documents (title, body) VALUES ('wadesk', '我们客户端也有群发https://wadesk.io');
INSERT INTO documents (title, body) VALUES ('Depois', 'Depois de comprar, tire um print da tela do preço e quantidade de compra e informe a assistente Michele . Ela ajudará a registrar e');

SELECT rowid, title, body FROM documents WHERE documents MATCH 'очень';

SQLite FTS5 可以自定义分词器

在进一步搜索过程中发现,微信在本地消息搜索过程中也有,消息检索的需求,且他们还做了进一步的优化

https://juejin.cn/post/6844903504419504135

进一步定位到一个针对中文搜索的优化库

https://www.wangfenjin.com/posts/simple-tokenizer/

这是一个开源的库,并且还给了使用 example,非常 Nice

simple/examples/node/node-sqlite3.js at master · wangfenjin/simple · GitHub

const path = require("path");
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');

// 获取应用路径
const ext_path = path.resolve(__dirname, 'lib');
const dict_path = path.resolve(__dirname, 'lib/dict');

db.serialize(function() {
    console.log("extension path: " + ext_path + ", dict path: " + dict_path);

    // 加载扩展
    const platform = process.env.npm_config_target_platform || process.platform;
    const arch = process.arch;

    if (platform === 'win32') {
        if (arch === 'x64') {
            db.loadExtension(path.join(ext_path, "libsimple-windows-x64.dll"));
        } else {
            db.loadExtension(path.join(ext_path, "libsimple-windows-x86.dll"));
        }
    } else if (platform === 'darwin' && arch === 'arm64') {
        db.loadExtension(path.join(ext_path, "libsimple-aarch64-linux-gnu-gcc.so"));
    } else if (platform === 'darwin' && arch === 'x64') {
        db.loadExtension(path.join(ext_path, "libsimple-osx-x64.dylib"));
    } else {
        db.loadExtension(path.join(ext_path, "libsimple-linux.so"));
    }

    // 设置 jieba 字典文件路径
    db.run("select jieba_dict(?)", dict_path);

    // 创建表并插入数据
    db.run("CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize = 'simple')");
    db.run("insert into t1(x) values ('周杰伦 Jay Chou:我已分不清,你是友情还是错过的爱情'), ('周杰伦 Jay Chou:最美的不是下雨天,是曾与你躲过雨的屋檐'), ('I love China! 我爱中国!我是中华人民共和国公民!'), ('@English &special _characters.\"''bacon-&and''-eggs%')");

    // 执行全文搜索
    db.each("select rowid as id, simple_highlight(t1, 0, '[', ']') as info from t1 where x match simple_query('zjl')", function(err, row) {
        console.log(row.id + ": " + row.info);
    });
    db.each("select rowid as id, simple_highlight(t1, 0, '[', ']') as info from t1 where x match simple_query('中国')", function(err, row) {
        console.log(row.id + ": " + row.info);
    });
    db.each("select rowid as id, simple_highlight(t1, 0, '[', ']') as info from t1 where x match jieba_query('中国')", function(err, row) {
        console.log(row.id + ": " + row.info);
    });
});

db.close();

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

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

相关文章

39. 647. 回文子串,516.最长回文子序列, 动态规划总结

确定dp数组以及下标的含义。如果大家做了很多这种子序列相关的题目,在定义dp数组的时候 很自然就会想题目求什么,我们就如何定义dp数组。绝大多数题目确实是这样,不过本题如果我们定义,dp[i] 为 下标i结尾的字符串有 dp[i]个回文串…

Weblogic 漏洞(详细)

一.weblogic弱口令 访问一下默认用户名:weblogic 密码: Oracle123 然后点击安装 然后再点击上传文件 将jsp木马打包,改为war上传一直下一步,最后点完成 然后使用工具连接 二.CVE-2017-3506 使用工具检测,存在漏洞 …

【C++】模拟实现stack

🦄个人主页:修修修也 🎏所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 ​ 目录 一.了解项目功能 📌了解stack官方标准 📌了解模拟实现stack 二.逐步实现项目功能模块及其逻辑详解 📌实现stack成员变量 &…

[pdf]240道《软件方法》强化自测题业务建模需求分析共201页(202408更新)

链接: http://www.umlchina.com/url/quizad.html 如果需要提取码:umlc 文件夹中的“潘加宇《软件方法》强化自测题业务建模需求分析共240题.pdf”

【MATLAB第107期】基于MATLAB的Morris全局敏感性分析模型(无目标函数)

【MATLAB第107期】基于MATLAB的Morris全局敏感性分析模型(无目标函数) 一、原理介绍 1.基本原理: Morris方法采用概率均匀抽样的方式估计每个模型输入因子在输出结果中的重要性,通过比较系统在不同输入参数值上的输出结果变化来…

智观察 | 行业赛道里的AI大模型

‍ “AI改变世界”被炒得热火朝天,结果就换来AI聊天? 实际上,在日常娱乐之下,AI正在暗暗“憋大招”,深入各行各业,发挥更专业的作用。 自动驾驶 最近“萝卜快跑”霸榜热搜长达一周,让无人驾…

ECMAScript 6 入门 学习 日志笔记 2024/8/6 13:59

就读书籍: ECMAScript 6 入门 作者:阮一峰https://www.ruanyifeng.com/ 个人理解笔记 { } 块级 函数不能先用后声明 Let 优先函数表达 不可重复声明同一变量 { letfunction (){ } } 不谈其他,只要在{ } 中即可 ,简单暴力理解 const 和 let 类似 …

语言模型-神经网络模型(二)

神经网络模型语言模型 神经网络模型神经网络的分类神经网络模型和Ngram对比应用一-话者分离对比优劣 应用二-数字归一化应用三-文本打标 神经网络模型 释义: 与ngram模型相似使用,前n个词预测下一个词,输出在字表上的概率分布;过…

【Playwright+Python】使用Playwright进行API接口测试

在当今的自动化测试领域,结合Web UI和API接口测试已成为提升测试覆盖率和效率的关键。Playwright作为一个强大的自动化测试工具,除了在Web UI测试中大放异彩,还能与Python结合,实现强大的API接口测试功能。本文将带你探索如何使用…

面试软件测试岗:经典面试题!全背下来,月薪10K起步...

背题是一个快速应付面试的方式,但如果你想在软件测试行业稳步前进、步步为营的话,建议大家还是有序学习软件测试知识,积累够了,转行、跳槽都是顺其自然的。 1、什么是兼容性测试?兼容性测试侧重哪些方面? …

告别录屏难题:2024四大热门电脑录屏软件推荐

进行在线教学、游戏直播、制作教程视频,录屏已成为我们日常生活和工作的重要需求。电脑怎么录屏?一款好用的录屏软件十分重要。今天,我们就来为大家推荐四款实用的电脑录屏工具。 1. 福昕录屏大师:专业级录屏,满足多样…

深入理解接口测试:实用指南与最佳实践(四)IHRM管理系统实战-项目分析

​ ​ 您好,我是程序员小羊! 前言 这一阶段是接口测试的学习,我们接下来的讲解都是使用Postman这款工具,当然呢Postman是现在一款非常流行的接口调试工具,它使用简单,而且功能也很强大。不仅测试人员会使用…

前端获取视频文件宽高信息和视频时长

安装 yarn add video-metadata-thumbnails | npm install video-metadata-thumbnails引入依赖包 import { getMetadata } from video-metadata-thumbnails使用 if (file.name.includes(mp4)) {if (file) {try {console.log(file)// 获取视频的元数据const metadata await …

Linux基础笔记分享(超详细~)

文章目录 Linux基础1.基础概念2.基础命令命令行快捷键自动补全: tab移动光标快速删除翻看历史命令终止程序退出登录清屏 查看命令帮助alias命令别名-快捷键pwd-类似于地图cd-类似于传送术mkdir-类似于合成装备touch-创建文件ls-类似于查看装备tree-打印目录层级结构cp-复制命令…

快速上手AWS cloudfront产品

AWS CloudFront,亚马逊推出的卓越全球内容分发网络服务,专为加速网站内容的极速传输而设计,旨在大幅度削减加载延迟,同时确保内容传递过程中的高度安全性和无懈可击的可靠性。借助CloudFront的强大功能,用户能够轻松实…

6个适用于Linux具有数据加密功能的绝佳软件和应用

数据加密在如今的网络安全领域是一个不可或缺的功能。该功能支持您编码数据,让没有访问权限的其他人无法读懂您的数据。若要增强在网络上的安全性,选择使用默认拥有此实用功能的软件或许是个不错的办法。 在本文中,您将了解到一系列运行在Li…

C++空指针(nullptr)

C空指针(nullptr) ​ 在C语言中我们把空指针定义成NULL,但是这在C中会有所问题,因为C对指针类型转换比较严格。下面让我来深入了解一下NULL与nullptr。 NULL实际就是一个宏,在C头文件(stddef.h)中,可以看到如下代码:…

vue3学习day03-vue3的生命周期、父子通信、模版引用、defineExpose

11、vue3的生命周期 (1)Vue2中生命周期: beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed (2)选项式API的生命周期: BeforeCreate/created、beforeMou…

TCP协议及ip

传输控制协议 通信前必须建立连接 tcp传输数据可靠 这就和大家的qq号和手机号一样 没有完全相同的qq号和手机号 端口号:1-65535 的一个整数 1-1024 通过端口号可确定哪一个程序在运行 应用程序的id 自定义端口号5999之后 在Qt中使用网络通信 套…