用户搜“python search”,页面返回40条结果,每条只显示一个标题。想找到真正匹配的那一段,还得逐条点开。好的搜索界面早就用同一种方式解决这个问题:在匹配位置截取一小段摘要,把查询词加粗。谷歌这么做,GitHub这么做,你的文档站也应该这么做。
不用上Elasticsearch
![]()
实现这个效果不需要引入Elasticsearch。纯Python全文搜索库Whoosh自带一套完整的高亮引擎。安装时用whoosh3,这是仍在维护的分支,导入时依然写whoosh。
一个值得设置的参数
搜索时传入terms=True。Whoosh通常能自己重建查询词,基础高亮不传也能用,但terms=True会让Whoosh精确记录每个文档匹配了哪些词。这对扩展查询更准确,比如通配符、前缀、模糊查询,还能调用hit.matched_terms()。开销很小,官方文档也推荐设置。
代码结构很直接:创建索引时用TEXT(stored=True)定义字段,写入文档后提交,搜索时解析查询并传入terms=True,然后遍历结果调用hit.highlights("body")。一个关键坑是:要高亮的字段必须存储,也就是TEXT(stored=True)。如果源文本存在数据库而不是索引里,就手动把文本传给highlights方法,写成highlights("body", text=my_text)。
默认输出与网页定制
开箱即用会得到带HTML标签的结果,匹配词被这类标签包裹。注意输出里的省略号,Whoosh已经自动挑出最相关的片段并拼接起来,这是fragmenter和formatter在起作用。
面向网页输出时,要设置的是results对象上的属性,不是hit对象。把formatter换成HtmlFormatter(tagname="mark", classname="hl", termclass="t"),fragmenter换成ContextFragmenter(maxchars=100, surround=30),就能生成标签,样式交给CSS控制。调用results[0].highlights("body", top=2)可以限制返回片段数量。
为什么这值得做
搜索结果页的核心不是返回更多条目,而是让用户快速判断哪条值得点开。高亮摘要把匹配上下文直接推到眼前,省掉来回切换的时间。Whoosh把这件事做成了几行配置,不需要额外服务,不需要改存储结构。对文档站、内部知识库、小型全文检索场景来说,这是成本最低的体验升级。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.