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 是空值合并运算符,如果 a 是 null 或者 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】搭建私人博客:搜索引擎

相关推荐
夏幻灵8 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
三天不学习9 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
Apipi*9 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
xcs1940510 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
天启HTTP10 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
广州浮点FLOATLIC12 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
BLUcoding13 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
AIgorithmGEEK13 小时前
[Linux]从手写报头到内核套路:序列化、反序列化与自定义协议全链路
linux·运维·服务器·网络·序列化·反序列化
Nil20813 小时前
leetcode 139单词拆分
linux·运维·服务器
Starry-sky(jing)13 小时前
BUG: unable to handle kernel paging request 完整排查:dmesg 四要素与三路定罪
linux·运维·服务器·内核·排障