108、【Ubuntu】【Hugo】搭建私人博客:搜索引擎

【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除

背景

上篇 blog
【Ubuntu】【Hugo】搭建私人博客:模糊搜索 Fuse.js(三)

分析了 Hugo PaperMod 搜索的默认配置项,以及支持用户可自定义的搜索配置项,下面继续

搭建私人博客

OK,下面来看 Fuse 搜索引擎实例的创建

这里面的两个参数:

  • data:从 index.json 里加载的文章数组
  • options:上面构建好的用户自定义配置对象

此时 new Fuse(...) 会遍历 data 中的每篇文章,并对 keys 指定的字段建立倒排索引 ,然后返回一个可复用的搜索对象,之后就可以通过 let results = fuse.search("ssh tunnel"); 这样返回匹配的文章列表(按相关性排序)

对关键字 keys 指定的字段建立倒排索引是搜索引擎(包括 Fuse.jsElasticsearchLucene 等)高效查找数据的核心原理,下面来详细分析下

正排索引

在分析倒排索引之前,先来看下正排索引,做个对比

假如有一本书,目录是这样的

标题 ID 内容
1 苹果很好吃
2 香蕉和苹果都是水果
3 大家喜欢吃苹果

这种格式就是正排索引,按标题索引内容,如果想知道第 2 篇文章写了什么,查一下标题 ID 就可以知道,但如果想知道哪些文章里有关键词【苹果】,就得逐篇扫描所有内容,那么效率就很低,时间复杂度 O(n)

倒排索引

OK,下面再来看上面提到的倒排索引,之前正排索引是【标题】->【内容】,现在倒排索引是【关键词】->【标题】,倒排索引会把上面举例的数据转换成下面这样:

关键词 标题 ID
苹果 [1,2,3]
很好吃 [1]
香蕉 [2]
水果 [2]
喜欢 [3]

可以看到,在倒排索引中,当用户搜索【苹果】关键词,搜索引擎直接查倒排表,就可以立马找到结果 [1,2,3],瞬间返回,而不需要扫描全文,时间复杂度从 O(n) 降到 O(log n),快的飞起

OK,回到 fastsearch.js,首先定义了关键字段 keys: ['title', 'summary', 'content']Fuse.js 在初始化时(new Fuse(data, options)),会遍历每一篇文章(data 中的每个对象),然后对 keys 中指定的每一个字段进行分词,并把每个词映射到包含它的文档 ID,举个例子,假设有两篇文章

javascript 复制代码
[
  {
    id: 1,
    title: "SSH 隧道教程",
    summary: "教你如何使用 SSH 反向隧道"
  },
  {
    id: 2,
    title: "Git 使用指南",
    summary: "Git 是分布式版本控制系统"
  }
]

Fuse.js 会对 title 和 summary 建立倒排索引(简化版)如下

文档 ID
ssh [1]
隧道 [1]
教程 [1]
使用 [1,2]
git [2]
分布式 [2]
版本控制 [2]

实际上,Fuse.js 还支持模糊匹配(比如 sssh 也能匹配 ssh),所以它的索引比传统倒排更复杂,但核心思想是一样的

OK,最后再来对比下传统搜索引擎和 Fuse.js 的倒排索引

特性 传统引擎(比如 Elasticsearch) Fuse.js
索引存储 磁盘/内存,支持持久化 纯内存,页面关闭就消失
分词 支持中文分词,同义词等 默认按空格/字母分词(对中文效果一般)
模糊匹配 需额外配置 内置强大模糊算法(基于 Levenshtein 距离)
适用场景 大型网站,海量数据 小型静态站(< 1000 篇文章)

Fuse.js 的倒排索引其实是为模糊搜索优化的内存结构,不完全等同于数据库的倒排,但思想一致

keys 指定的字段建立倒排索引,就是把文章中指定字段(比如标题,摘要等)中的每个词进行分类,预先记录这个词会出现在哪些文章里,这样搜索时就能秒级定位结果,而不用一片片翻,这是所有现代搜索引擎(从 Google 到博客搜索框)高效工作的基石


OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:搜索功能(五)

相关推荐
热忱11282 小时前
Git 全套常用命令手册(含日常开发示例)
大数据·git·elasticsearch·搜索引擎
很㗊2 小时前
奇技淫巧之花里胡哨的VIM---插件的添加与美化
linux·ubuntu·vim
Java后端的Ai之路2 小时前
【Python小知识】-self是什么?
linux·python··self
kaoa0002 小时前
Linux入门攻坚——63、tcpdump、nc/ncat、nmap等工具的使用
linux·运维·tcpdump
CAU界编程小白2 小时前
Linux系统编程系列之进程信号
linux·信号
开开心心就好2 小时前
卸载工具清理残留,检测垃圾颜色标识状态
linux·运维·服务器·python·安全·tornado·1024程序员节
小舞O_o2 小时前
gitlab文件上传
linux·服务器·git·python·目标检测·机器学习·gitlab
HalvmånEver2 小时前
Linux:信号捕捉下(信号四)
linux·运维·数据库
咕咕嘎嘎10242 小时前
Socket编程
linux·服务器·网络