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

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

背景

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

分析了模糊搜索的概念,以及 Fuse.js 的核心原理,下面继续

搭建私人博客

OK,接下来继续看 fastsearch.js 的实现

当解析到 JSON 内容后,这里定义了 Fuse.js 的几个核心配置选项,这些选项将决定搜索如何匹配关键词,下面详细说下这里的选项:

  • keys定义在哪些字段中搜索 ,这里默认值是 ['title', 'permalink', 'summary', 'content'],用户输入的关键词会在这几个字段里面匹配
  • threshold:匹配阈值,这里默认值 0.4,范围(0.0 ~ 1.0),其中
    0.0 = 完全精确匹配
    0.4 = 允许较多错误,比如漏字,顺序错等
    1.0 = 任意字符都算匹配(不推荐)
  • distance:模糊匹配半径,默认值 100,需要配合关键词 location 来使用,表示关键词偏离理想位置多远仍可以接受,不过这里 ignoreLocation 为 true,那 location 参数就没啥影响
  • ignoreLocation:是否忽略关键词在文本中的位置,默认值 true
    true:全文平等对待,适合博客这样的全文搜索
    false:优先匹配开头,适合命令,文件名的搜索方式

这套默认配置很适合博客或者文档站点,因为用户可能记不清完整标题,但关键词还是记得几个的

OK,下面继续看下面的用户自定义配置

前面 blog 说过,import * as params... 表示从 Hugo 构建系统(hugo.toml 配置文件)导入配置参数

这是 Hugo 的 JS 构建管道特性,在模板中,可以把站点配置传入 JS,比如

go 复制代码
{{ $searchJS := resources.Get "search.js" | js.Build (dict "params" .Site.Params.search) }}

比如 Hugo PaperMod 是在 head.html 模板中传入站点配置的

然后可以在 Hugo 自定义配置文件 hugo.toml 中定义

yaml 复制代码
params:
  search:
    fuseOpts:
      threshold: 0.3
      keys: ["title", "tags"]

另外,这里的 ?? 有点类似 C 语言的三元运算符用法

x: a ?? b 是空值合并运算符,如果 anull 或者 undefined,就用 b 作为 x 的值,这样既允许用户覆盖,又可以保留安全默认值,下面来详细说下里面的自定义选项

  • isCaseSensitive:表示是否区分大小写,用户没定义的话,默认 false
  • includeScore:是否在结果中包含匹配分数(调试用),默认 false
  • includeMathces:是否返回匹配位置(高亮用),默认 false
  • minMatchCharLength:最少输入几个字符才开始搜索,默认 1 个字符就开始搜索
  • shouldSort:是否按匹配度排序结果,默认 true
  • findAllMatches:是否查找所有匹配,而不是只找第一个,默认 false
  • keys:自定义搜索字段,如果没有自定义的话,默认就是上面提到的 ['title', 'permalink', 'summary', 'content']
  • location:匹配的起始位置(配合 distance 选项使用),默认是 0
  • threshold/distance/ignoreLocation:上面提到过了,这里不再赘述

这种设计方式,可以让用户在 hugo.toml 站点的配置文件修改,就能调优搜索体验,而无需修改 JS 代码,很方便

最后,这里再额外补充下 findAllMatches 选项,这里默认 false 不是代表只返回一个搜索结果,这个选项和返回多少文档没有关系,findAllMatches 表示的是在单个字段内,是否查找多个匹配位置,而不是控制返回多少篇文章(搜索结果) ,搜索结果数量由 fuse.search(query, { limit: N }) 决定,与 findAllMatches 无关

举个例子,假设由一篇文章

javascript 复制代码
{
  title: "SSH tunnel and reverse tunnel guide",
  content: "Learn how to set up SSH tunnel. Tunnel is powerful."
}

里面有很多 tunnel 关键词,此时用户搜索 tunnel 这个关键词,有两种情况

  • findAllMatches: false:默认选项,此时 Fuse.js 在 title 字段中找到第一个 tunnel 就停止,在 content 字段中也只记录第一个匹配位置,但整篇文章仍然被作为搜索结果返回(匹配度够高)
  • findAllMatches: true:此时 Fuse.js 会找出 title 中所有 tunnel 的位置,同样也会找出 content 中所有匹配的位置,返回的文章数量不变,但每篇文章的 matches 数组里会有多个匹配项

这个功能主要用于前端高亮显示,如果想把文章中所有匹配词都标红,就把 findAllMatches 设置为 true


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

相关推荐
一粒黑子7 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
IT枫斗者7 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
有谁看见我的剑了?7 小时前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
Beginner x_u8 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
我叫汪枫8 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch8 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI8 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0018 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
念2348 小时前
f5 shape分析
开发语言·javascript·ecmascript
難釋懷8 小时前
Vue混入
前端·javascript·vue.js