全文检索
OINK 的搜索是本地搜索:Hugo 在构建时给每种语言生成一份 JSON 索引,读者的浏览器下载它,在本地完成检索。不需要爬虫、账号、CDN,也不需要联网。主题默认不启用,一行配置即可开启。
搜索的入口是命令面板,打开方式与面板的其余内容见命令面板。
打开本地搜索
这一个键决定索引、Lunr 运行时与搜索对话框是否进入页面。三个条件同时成立时页面才带上它们:
params.offline_search为真;- 页面是首页,或者用了外壳布局(
docs/book/blog/swagger,见布局与页面类型),或者是开着params.ui.landing_search的落地页; - 当前输出不是打印。
任何一条不成立,构建就不往这个页面里放对话框、索引引用与 Lunr。这些资源不是被隐藏,而是不生成。
hugo server 下索引默认 也会生成,预览行为与线上一致。站点极大、每次改动都重建全站索引明显拖慢预览时,把它关掉:
控制索引体积
offline_search_index 决定每个页面往索引里写多少内容,因此同时决定两件事:读者能否搜到正文里的词,以及第一次搜索要下载多大的文件。
| 取值 | 索引进去的内容 | 什么时候用 |
|---|---|---|
title |
标题、标签、分类、search_keywords |
只靠标题定位的超大站 |
heading |
上面这些 + 页内各级标题 | 标题写得足够具体时 |
summary |
上面这些 + 描述与摘要 | 千页级站点;本站使用这一档 |
content |
上面这些 + 全文纯文本 | 默认值,几百页以内适用 |
其它取值构建失败,报 invalid params.offline_search_index。
offline_search_summary_length 是结果行里摘要的截断长度(默认 70),offline_search_max_results 是结果条数上限(默认 10)。这几个键的完整定义在配置总览。
读者搜第一个词之前要先下载整份索引。超过这个量级就把 offline_search_index 从 content 降到 summary。
调整排序
页面在 front matter 里影响自己的排名:
search_keywords 是额外的匹配词,可以写一个字符串,也可以写数组。它是这两个键里更有用的一个:读者搜 pg 或 GUC 即可命中标题只写着「PostgreSQL 参数」的页面。检索时关键词的权重仅次于标题,高于正文。
search_boost 是最终得分的正数乘子,默认 1.0,作用在文本匹配得分之上。1.5 不会把页面固定在第一位,只让它在本来就匹配的结果里前移。零、负数与非数字会告警并按 1.0 处理。
整节的默认值用 cascade 一次设定:
页面自己写的值覆盖继承来的值。本站 docs/ 下的页面按这种方式使用 search_keywords:每页列出中文说法、英文原词与配置键名。
把页面挡在索引外
search_exclude 是唯一写法,exclude_search 与 excludeSearch 会让构建失败并提示改名。正文为空的页面不进索引。
不该公开的内容不要放进站点,也不要用 search_exclude 保护它。
中文与 CJK
Lunr 不能可靠地给中文分词。面板在查询里检测到 CJK 字符时整条切到子串匹配:逐篇比对标题、关键词、页内标题、描述、正文,命中哪一层给哪一层的分,最后同样乘上 search_boost。两条路径的排序规则一致。
三点需要知道:
- 中文查询是 子串 匹配。搜「主从复制」只命中连续出现这四个字的位置,搜「复制主从」没有结果。
search_keywords对中文站的收益因此最大:把读者可能使用的同义说法、英文原词、缩写都写进去。- 输入法组字期间面板不重算结果,文字上屏后才检索,中文输入不会逐字母刷新结果。
中文搜不到内容时,先确认中文页面进了中文那份索引(见下面的验证),再考虑分词问题。
可选:在线搜索
本地搜索之外,主题保留了两个在线搜索集成,默认关闭。同一时间只启用一种:配置了多个入口时构建告警 You have more than one site-search option configured。
启用在线搜索意味着接受对应服务的抓取方式、可用性与隐私边界,这些应写进站点的隐私说明。
Algolia DocSearch
三个值必须都显式写出,缺一个构建中断:OINK 不会回退到其它项目的公共索引。DocSearch 的 JS 与 CSS 随主题内置,不从 CDN 加载,但每次检索请求都发到 Algolia。需要真实的密钥与索引才能工作,此处不渲染。
Google 可编程搜索
还需要给结果准备一个落地页:
搜索框把查询提交到 <baseURL>/search/?q=…,结果由 Google 的脚本在那个页面上渲染,需要访问 cse.google.com。同样需要外部服务,此处不渲染。
验证
-
构建,确认每种语言各生成了一份索引:
开发构建下文件名是
offline-search-index.zh.json,生产构建加指纹,形如offline-search-index.zh.7ab….json。一种语言一个文件,缺少某个文件说明那种语言的页面没进索引。 -
查看索引内容,这是排查「中文搜不到」的第一步:
条目数应接近中文页面数,
keywords与boost字段能看到写进 front matter 的值。 -
打开站点,按 /,分别用一个英文词与一个中文词各搜一次。结果按内容根分组,每组的名字是面包屑的第一段。
-
子路径部署(站点挂在
https://example.com/docs/这类路径下)时,打开浏览器开发者工具的网络面板,确认索引请求带上了子路径。索引请求打到域名根目录并返回 404、页面其余部分正常,是「搜索没结果」最常见的原因。
相关
- 命令面板 — 搜索的入口,以及面板里的命令与页面动作
- 键盘导航 — 打开搜索与打开命令的四个单键
- 多语言 — 分语言索引与缺译回退
- 配置总览 —
offline_search*各键的完整定义 - 页面参数 —
search_keywords/search_boost/search_exclude