【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【Ubuntu】【Hugo】搭建私人博客:模糊搜索 Fuse.js(一)
分析了解析 JSON 数据,以及 Fuse.js 不同版本的区别,下面继续
搭建私人博客
fuse.basic.min.js 本身也是 Fuse.js 的一部分,属于基础压缩版本,后面用 Fuse.js 统一指代 fuse.basic.min.js

下面先介绍下模糊搜索
模糊搜索
介绍模糊搜索前,先看一下传统的精确搜索方式:
- 在搜索框输入【苹果手机】
- 此时系统只返回完全包含【苹果手机】这四个字的匹配内容
- 如果文章写的是【iPhone 手机】或【苹果智能手机】,就搜不到,因为精确搜索要求的是全字匹配
然后再来看更智能的模糊搜索:
- 在搜索框输入【平果手机】(打错字),或【水果机】(谐称),或者【手机苹果】(顺序颠倒)
- 此时系统依然能猜出用户想找的是【苹果手机】,并返回相关结果
从上面的例子可以看出来,模糊搜索是可以容忍拼写错误,部分匹配,顺序错乱,以及近似词的智能搜索方式
再举些平时可能会发生的例子
| 输入 | 精确搜索结果 | 模糊搜索结果 |
|---|---|---|
| Gogle | 无(拼写错误) | 返回 Google |
| ubntu | 无 | 返回 Ubuntu |
| ssh tunnel | 无 | 返回 SSH tunnel(大小写) |
所以平常在 Github,VSCode 里打错字也能搜到东西,因为这些 App 都用了模糊搜索
OK,介绍完模糊搜索概念,下面再来看 Fuse.js
Fuse.js
Fuse.js 是一个轻量级,零依赖的 JavaScript 库,用于在浏览器或 Node.js 中实现快速模糊搜索 ,其 Github 开源仓库地址 https://github.com/krisk/Fuse,纯前端内容,无需服务器,并且也支持中文,配置灵活,下面举个例子看其使用方法
- 假设有以下数据
javascript
const books = [
{ title: "《三体》", author: "刘慈欣" },
{ title: "《流浪地球》", author: "刘慈欣" },
{ title: "《基地》", author: "阿西莫夫" }
];
- 用
Fuse.js进行模糊搜索
javascript
const fuse = new Fuse(books, { keys: ["title", "author"] });
fuse.search("liucixin"); // 匹配【刘慈欣】
fuse.search("san ti"); // 匹配【三体】
fuse.search("liut"); // 可能匹配【刘慈欣】(因为 liut ≈ liu t)
可以看到,即使拼错,少字,空格错位,Fuse.js 也能找到最可能的结果
Fuse.js 核心原理(简化)
Fuse.js 使用 Bitap 算法 + 动态规划,计算两个字符串的编辑距离(把 A 字符串变成 B 字符串,需要最少改动的字母个数),比如
kitten->sitting:需要三步,k->s,e->i,最后补个g
那么其编辑距离就是 3,然后 Fuse.js 会对每个字段(比如标题,摘要等)计算与关键词匹配的相似度分数,再根据阈值判断是否算匹配,最后按匹配度排序返回结果
Fuse.js 有这么几个特点,使得其非常适合类似 Hugo 这样的静态网站
- 不需要后端数据库
- 所有搜索在用户浏览器完成,离线也可以使用,只不过搜索到打不开
- 首次加载
index.json后,后续搜索飞快
但不适合
- 数据量极大(>10万条),内存爆炸(私人博客正常情况下写不了这么多,一个人一生也就 3 万天(包括婴儿和老年),一天写一篇也到不了这么多)
- 需要复杂查询,比如【价格 < 100 并且品牌 = Apple】,这种用
elasticsearch
简而言之,模糊搜索属于能猜到用户想搜什么的智能搜索,而 Fuse.js 就是可以在网页里轻松实现模糊搜索的 JavaScript 工具,可以让博客,文档站,知识库拥有打错字也能搜到的现代搜索体验,而无需搭建复杂的后端服务,所以 Hugo PaperMod 用的就是这样的一个轻量化搜素引擎
最后再对比下精确搜索和模糊搜索的实现与特点
| 实现&特点 | 精确搜索 | 模糊搜索 |
|---|---|---|
| 是否容错 | 否 | 是 |
| 部分匹配 | 不支持,必须完整词 | 可以支持,比如 ubun,可以联想到 Ubuntu |
| 性能 | 极快(基于哈希表) | 快(但需要遍历和计算) |
| 实现难度 | 简单,indexof,只要知道索引即可 | 中等,需要算法库 |
| 用户体验 | 差(容错低) | 好 |
OK,本篇先到这里,如有疑问,欢迎评论区留言讨论,祝各位功力大涨,技术更上一层楼!!!更多内容见下篇 blog
【Ubuntu】【Hugo】搭建私人博客:模糊搜索 Fuse.js(三)