Node-js用FlexSearch给Hexo添加极速全站搜索
全站检索,全站内容搜索之自定义flexsearch实现【已上线,V0.0.2测试中】
引用拓展:大文本,多文本,多文件系统级文本字符低资源消耗高效急速搜索
有什么用
许多网站或博主都苦于站内搜索的功能缺陷,使用特定搜索引擎的搜索就得要忍耐特定搜索引擎收录文章的速度(搜索内容受局限于特定的旧版本),自带的搜索消耗太多资源,速度慢,html的静态站点无法使用数据库的搜索.....
介绍flexsearch(这个可以轻易从加速浏览器中搜索获取最新版信息)不是本文的重点,Node.js的入门在我上一篇文章是重点:Node.js开发环境及应用实例
本文主要分享Node.js + FlexSearch 实际应用在本站(hexo)中全文搜索实现,用于我在Carl Notes 博客园中同步发布文章时“相关内容”章节的实现(iframe方法,由于博客园禁止了在文章中添加javascript代码,导致ajax跨域去cdn站点里面获取相关内容失败,这是一个巨坑,坑了我好2-3天)
使用FlexSearch对于内容的搜索是很有帮助是它的强项,Hexo对于相关内容的实现也不错:用插件中的算法去比对我目前300多篇文章彼此之间的联系,关键字,权重等等。详细见 Hello hexo中关于相关文章 related_posts 如何增加到10条?的章节介绍
但hexo(我目前的版本)在全站搜索的实现是潦草了,不知道最新版有没有改进‘全站检索‘
hexo: 6.3.0
hexo-cli: 4.3.1
# 我的hexo待更新啊。。。懒。。。新版吸引力不足。。。
node: 20.10.0
目前版本的hexo是通过ajax请求把search.xml,比如这样的 search.xml下载到内存中,然后通过js来在本地浏览器搜索和匹配(优点:UI界面很好看)可是,可是我的文件截止目前为止已经3M了!
可是这对于WEB太大了,我用最快的CDN线路,最快也要花费350ms+才能下载到本地,一般的cdn都要1s+这对于用户是很要命的。这是在方案级别上的缺陷。
怎么用
使用了目前(2023年12月中旬)是最新版本的FlexSearch
最简单的使用:
//申明三种情况的应用,从简单到复杂Index,Document和Worker;先理解最简单的Index
const {Index, Document, Worker} = require("flexsearch");
//指定Index索引的参数,可以很复杂,先从默认最简单的开始
const index = new Index({
tokenize: "reverse",
depth: 2,
minlength: 3
});
//添加源内容,比如多个文件,数据库。。。
index.add(post.title, post.title + post.source + post.content)
//搜索,参数限定了11个结果
var searchRes = index.search(req.query.q, 11);
相关内容
实现方法/过程
基础学习建议实践走一下流程:https://expressjs.com/en/starter/installing.html
(在试一试列子https://expressjs.com/en/starter/examples.html)
Express, jade相关
#主程序文件app.js,文件内容节选:
var appSearchRouter = require('./routes/appsearch');
#这里引用的新建的文件appserach.js
app.use('/appsearch', appSearchRouter); #这个注册appsearch可以按需修改名称
#其他的文件内容都按默认的列子https://expressjs.com/en/starter/examples.html
#生成的默认的文件列表即可。文档很清晰,友好。
#appsearch.js文件内容Express, jade相关:
var express = require('express');
var router = express.Router();
res.render('searchTemplate', { searchResults: arrSearchRes });
#对应下面的searchTemplate.jade文件内容:
#然后在views目录下面添加searchTemplate.jade文件,文件内容:
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
.popup.search-popup
.search-result-container
.search-stats 找到 #{searchResults.length} 个搜索结果
hr
ul.search-result-list
each result in searchResults
li
a(href=result.doc.url, class="search-result-title", data-pjax-state="")
mark.search-keyword= result.doc.title
a(data-pjax-state="" href=result.doc.url)
p.search-result= result.doc.subcontent
FlexSearch相关
#appsearch.js文件内容中FlexSearch相关:
const {Index, Document, Worker} = require("flexsearch");
//const document
const index = new Document({
tokenize: "reverse",
minlength: 3,
document: {
id: "id",
index: [
// { 没必要用title在搜索一遍,即便效率极高
// field: "title",
// tokenize: "forward"
// },
{
field: "content",
context: {
// depth: 2,
// resolution: 3
},
tokenize: "reverse"
}],
store: ["title", "updated", "date", "source", "content"]
}
});
// load posts from a file 加载hexo的数据库文件
var pages = JSON.parse(require('fs').readFileSync(path.join(__dirname, '../../blog/db.json')).toString()).models.Post;
// add posts to the index
pages.forEach(post => {
var idx = 1;
// index.add(post.title, post.title + post.source + post.content)
index.add({
id: post.title,
title: post.title,
"title": post.title,
"updated": post.updated,
"date": post.date,
"source" : post.source,
"related_posts": post.related_posts,
content: post._content
})
idx ++;
});
var arrSearchRes = index.search(req.query.q, {
limit: 11,
enrich: true
});
注意避坑事项1
// create the index
// var FlexSearch = require("flexsearch");
// var index = FlexSearch.create();
这是flexsearch的旧版本语法,Google了一圈,国内的(中文内容)很多例子都是这个旧版本的,旧版本是无法运行的,各种报错,连ChatGpt3.5都不会解释,问题出现在哪里了。(这告诉我们版本是多么重要的)
注意避坑事项2
jade模版也是很好用的,缩紧语法。很简易地将HTML生成。制作过程中,也能很容易地使用转换工具,将现成的HTML转化为jade(或者Pug)的模版,比如:https://tool.fiaox.com/template-html-pug/
模版转化,模版转换Html to Pug
添加CORS跨站支持
res.setHeader("Access-Control-Allow-Origin","*");
res.setHeader(
"Access-Control-Allow-Methods",
"PUT, GET, POST, DELETE, HEAD, PATCH"
);
Docker中Production发布
Docker中发布是我首选项,高效简单易管理。
发布文件列表:
复制所有文件夹除了node_modules
#进入nodejs容器,启动bash(用于执行node程序们)
> docker exec -it nodejs bash
#直接运行node程序:
> node /home/app/blogsearch/bin/www
#或者进入目录在运行
> cd h.........
# [继续阅读](https://carlzeng.top/202312161121.html)
[请点击访问最新版内容](https://carlzeng.top/202312161121.html)