自建搜索引擎-基于美丽云
Meilisearch 是一个搜索引擎,主程序完全开源,除了使用官方提供的美丽云服务(收费)进行对接之外,还可以通过自建搜索引擎来实现完全独立的搜索服务。
由于成本问题,本博客采用自建的方式,本文就讲讲怎么搭建。
本文主要参考:
- meilisearch 全接入指南 | 二丫讲梵:讲了怎么使用官方提供的服务,也讲了怎么自建
- Meilisearch Documentation:官网文档
前置工作
- 博客已配置 sitemap 功能,参考 VuePress 博客之 SEO 优化(一)之 sitemap 与搜索引擎收录 - 知乎
- 自建时要用到自定义的域名,因此额外购买了一个二级域名的 SSL 证书,例如我用的是 search.peterjxl.com
安装和启动美丽云
首先需要在服务器上安装美丽云搜索:
curl -L https://install.meilisearch.com | sh
我在用 curl 安装的时候,发现有报错,推测是 GFW 的问题,改为用 Docker 安装(有很多安装方式,参考安装指南):
docker pull getmeili/meilisearch:v1.6
然后启动命令格式为:
docker run -itd --name meilisearch -p 7700:7700 \-e MEILI_ENV="production" -e MEILI_NO_ANALYTICS=true \-e MEILI_MASTER_KEY="自定义一个不少于16字节的秘钥" \-v $(pwd)/meili_data:/meili_data \getmeili/meilisearch:v1.6
注意修改 master-key,该密钥用于爬虫抓取使用(就是爬取你的博客内容并做好分词、索引等)。
启动后可以用 docker ps 查看容器状态,或者用 telnet 检查端口是否被监听。
配置 Nginx
首先去阿里云上配置 DNS 解析记录:

这个结合自身情况添加配置(例如我用的是 Nginx):
server {listen 80;listen 443 ssl;server_name search.peterjxl.com;ssl_certificate /conf/search.peterjxl.com.pem;ssl_certificate_key /conf/search.peterjxl.com.key;ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;ssl_protocols TLSv1 TLSv1.1 TLSv1.2;ssl_prefer_server_ciphers on;location / {proxy_set_header Host $host;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-Real-IP $remote_addr;proxy_pass http://127.0.0.1:7700;}}
配置后记得重启 Nginx,并且记得开通防火墙,然后尝试访问子域名,可以看到正常转发了请求:

建立索引
接下来,我们通过美丽云提供的爬虫功能,将博客数据创建成索引,相关文档请见:Integrate a relevant search bar to your documentation — Meilisearch documentation。
其中,提供了一个关于 VuePress 的配置文件模板:
If you use VuePress for your documentation, you can check out the configuration file we use in production. In our case, the main container is
theme-default-content and the selector titles and subtitles areh1,h2…
{"index_uid": "docs","sitemap_urls": ["https://docs.meilisearch.com/sitemap.xml"],"start_urls": ["https://docs.meilisearch.com"],"selectors": {"lvl0": {"selector": ".sidebar-heading.open","global": true,"default_value": "Documentation"},"lvl1": ".theme-default-content h1","lvl2": ".theme-default-content h2","lvl3": ".theme-default-content h3","lvl4": ".theme-default-content h4","lvl5": ".theme-default-content h5","text": ".theme-default-content p, .theme-default-content li, .theme-default-content td"},"strip_chars": " .,;:#","scrap_start_urls": true,"custom_settings": {"synonyms": {"relevancy": ["relevant", "relevance"],"relevant": ["relevancy", "relevance"],"relevance": ["relevancy", "relevant"]}}
}
注意如上的配置内容很重要,如果你的博客不是常规默认的,那么需要根据自己的情况对元素进行辨别,详细配置项说明,参考官方文档:更多可选字段 。
我用的配置如下:
{"index_uid": "VuePressBlog","sitemap_urls": ["https://www.peterjxl.com/sitemap.xml"],"start_urls": ["https://www.peterjxl.com"],"selectors": {"lvl0": {"selector": "h1","global": true,"default_value": "Documentation"}, "lvl1": ".theme-vdoing-content h2","lvl2": ".theme-vdoing-content h3","lvl3": ".theme-vdoing-content h4","lvl4": ".theme-vdoing-content h5","lvl5": ".theme-vdoing-content h6","text": ".theme-vdoing-content p, .theme-vdoing-content li"}, "strip_chars": " .,;:#","scrap_start_urls": true,"selectors_exclude": ["iframe", ".katex-block", ".md-flowchart", ".md-mermaid", ".md-presentation.reveal.reveal-viewport", ".line-numbers-mode", ".code
-group", ".footnotes", "footer.page-meta", ".page-nav", ".comments-wrapper"]
index_uid :为索引名称,如果服务端没有,则会自动创建。接下来我们将这个配置文件放到服务器上,然后通过如下命令运行爬虫对内容进行抓取(注意修改相关参数):
docker run -t --rm \--network=host \-e MEILISEARCH_HOST_URL='二级域名,例如我的是search.peterjxl.com' \-e MEILISEARCH_API_KEY='刚刚创建的Master Key' \-v 配置文件完整路径:/docs-scraper/config.json \getmeili/docs-scraper:v0.12.7 pipenv run ./docs_scraper config.json
执行过程中可以看到每个页面都进行了抓取(爬取过程会比较久,这取决于博客的内容数量):

创建搜索用的 key
在美丽云中,有两种密钥:
- master-key:权限很大,例如创建,更新,删除索引。
- API Key:权限很小,一般只用于搜索,可以有多个
更多说明可以参考官网文档:Master key and API keys — Meilisearch documentation。
由于 master-key 权限很大,不宜暴露,因此我们可以创建一个只有搜索权限的 API Key(用来搜索),命令格式:
curl \-X POST 'http://localhost:7700/keys' \-H 'Content-Type: application/json' \-H 'Authorization: Bearer 刚刚自定义的master-key' \--data-binary '{"description": "peterjxl.com search_key","actions": ["search"],"indexes": ["刚刚创建的index_id"],"expiresAt": "2099-01-01T00:00:00Z"}'
然后会返回一串 JSON,其中的 key 就是我们需要的(已脱敏):
{"name": null,"description": "peterjxl.com search_key","key": "xxxx","uid": "xxxx","actions": ["search"],"indexes": ["wiki"],"expiresAt": "2099-01-01T00:00:00Z","createdAt": "2024-01-17T12:54:42.357819802Z","updatedAt": "2024-01-17T12:54:42.357819802Z"
}
测试搜索
我们可以使用 Postman 来测试搜索效果(如果使用了美丽云的服务,可以在其官网进行搜索测试)
相关文档:Postman collection for Meilisearch — Meilisearch documentation (图片需科学上网后看到)
配置好后,可以进行搜索,效果如下:

配置 VuePress
接下来就是在 VuePress 中集成美丽云了。
客户端的配置相对简单,因为 meilisearch 的官方文档用的也是 Vuepress,因此官方也维护了一个 Vuepress 的插件,安装:
npm install vuepress-plugin-meilisearch
然后在配置插件的部分添加相关配置:
// 全文搜索插件 meilisearch['vuepress-plugin-meilisearch',{hostUrl: 'https://search.peterjxl.com', // meilisearch 服务端域名apiKey: "刚刚创建的搜索key", // 只有搜索权限的 keyindexUid: 'VuePressBlog',placeholder: '支持全文搜索', // 在搜索栏中显示的占位符maxSuggestions: 9, // 最多显示几个搜索结果cropLength: 30, // 每个搜索结果最多显示多少个字符},],
然后本地运行,试试效果:

配置 GitHub Action
如果每次更新了博客,都重新运行建立索引的命令,也太麻烦了。我们可以脚本化,或者使用 GitHub Action。例如,添加如下配置:
scrape-docs:needs: test_websiteruns-on: ubuntu-20.04steps:- uses: actions/checkout@v2- uses: actions/setup-node@v2with:node-version: 14registry-url: https://registry.npmjs.org/- name: Run docs-scraperenv:API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}CONFIG_FILE_PATH: ${{ github.workspace }}/docs/.vuepress/public/data/docs-scraper-config.jsonrun: |docker run -t --rm \-e MEILISEARCH_HOST_URL="https://search.peterjxl.com" \-e MEILISEARCH_API_KEY=$API_KEY \-v $CONFIG_FILE_PATH:/docs-scraper/config.json \getmeili/docs-scraper:v0.12.7 pipenv run ./docs_scraper config.json
注意这 3 个配置:
secrets.MEILISEARCH_API_KEY:就是 Master keyCONFIG_FILE_PATH:爬虫抓取时的配置文件,可以选择放在项目源码的某个指定目录(例如我的是docs/.vuepress/config/)MEILISEARCH_HOST_URL:美丽云的域名,例如我的是https://search.peterjxl.com
配置完后,当我们提交了新的代码,就会自动爬取博客数据并更新索引了,GitHub Action 执行情况:

(完)
相关文章:
自建搜索引擎-基于美丽云
Meilisearch 是一个搜索引擎,主程序完全开源,除了使用官方提供的美丽云服务(收费)进行对接之外,还可以通过自建搜索引擎来实现完全独立的搜索服务。 由于成本问题,本博客采用自建的方式,本文就…...
2024辽宁省大学数学建模竞赛试题思路
A题 (1) 建立模型分析低空顺风风切变对起飞和降落的影响 模型假设 飞机被视为质点,忽略其尺寸和形状对风阻的影响。风切变仅考虑顺风方向的变化,忽略其他方向的风切变。飞机的飞行速度、高度和姿态(如迎角、俯仰角)是变化的&am…...
循环结构(一)——for语句【互三互三】
文章目录 🍁 引言 🍁 一、语句格式 🍁 二、语句执行过程 🍁 三、语句格式举例 🍁四、例题 👉【例1】 🚀示例代码: 👉【例2】 【方法1】 🚀示例代码: 【方法2】…...
【深度学习基础】MacOS PyCharm连接远程服务器
目录 一、需求描述二、建立与服务器的远程连接1. 新版Pycharm的界面有什么不同?2. 创建远程连接3. 建立本地项目与远程服务器项目之间的路径映射4.设置保存自动上传文件 三、设置解释器总结 写在前面,本人用的是Macbook Pro, M3 MAX处理器&am…...
微调Qwen2大语言模型加入领域知识
目录 试用Qwen2做推理安装LLaMA-Factory使用自有数据集微调Qwen2验证微调效果 试用Qwen2做推理 参考:https://qwen.readthedocs.io/en/latest/getting_started/quickstart.html from transformers import AutoModelForCausalLM, AutoTokenizer device "cuda…...
【Linux】内核文件系统系统调用流程摸索
内核层可以看到当前调用文件处理的进程ID 这个数据结构是非常大的: 我们打印的pid,tgid就是从这里来的,然后只需要找到pid_t的数据类型就好了。 下图这是运行的日志信息: 从上述日志,其实我也把write的系统调用加了入口的打印信…...
【HZHY-AI300G智能盒试用连载体验】文档资料
感谢电子发烧友和北京合众恒跃科技有限公司提供的的产品试用机会。 HZHY-AI300G工业级国产化智盒,采用RK3588工业级芯片组适应-40℃-85℃工业级宽温网关。 以前测试过其他厂家的RK3568产品,对瑞芯微的工具也比较了解。 在合众恒跃的网站上可以看到基本…...
Linux--深入理与解linux文件系统与日志文件分析
目录 一、文件与存储系统的 inode 与 block 1.1 硬盘存储 1.2 文件存取--block 1.3 文件存取--inode 1.4 文件名与 inode 号 编辑 1.5 查看 inode 号码方法 1.6 Linux 系统文件的三个主要的时间属性 1.7 硬盘分区结构 1.8 访问文件的简单了流程 1.9 inode 占用 1.…...
Postman 中的 API 安全性测试:最佳实践与技巧
在当今快速发展的数字化世界中,API(应用程序编程接口)已成为软件系统之间通信的桥梁。然而,随着API使用的增加,安全风险也随之上升。本文将详细介绍如何在 Postman 中进行 API 的安全性测试,帮助开发者和测…...
PTC可复位保险丝 vs 传统型保险丝:全面对比分析
PTC可复位保险丝,又称为自恢复保险丝、自恢复熔断器或PPTC保险丝,是一种电子保护器件。它利用材料的正温度系数效应,即电阻值随温度升高而显著增加的特性,来实现电路保护。 当电路正常工作时,PTC保险丝呈现低阻态&…...
深入了解Rokid UXR2.0 SDK内置的Unity AR Glass开发组件
本文将了解到Rokid AR开发组件 一、RKCameraRig组件1.脚本属性说明2.如何使用 二、PointableUI组件1.脚本属性说明2.如何使用 三、PointableUICurve组件1.脚本属性说明2.如何使用 四、RKInput组件1.脚本属性说明2.如何使用 五、RKHand组件1.脚本属性说明2.如何使用3.如何禁用手…...
Lottery 分布式抽奖(个人向记录总结)
1.搭建(DDDRPC)架构 DDD——微服务架构(微服务是对系统拆分的方式) (Domain-Driven Design 领域驱动设计) DDD与MVC同属微服务架构 是由Eric Evans最先提出,目的是对软件所涉及到的领域进行建…...
我的AI音乐梦:ChatGPT帮我做专辑
🌈个人主页:前端青山 🔥系列专栏:AI篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来ChatGPT帮我做音乐专辑 嘿,朋友们! 想象一下,如果有个超级聪明的机器人能帮你写…...
新手-前端生态
文章目录 新手的前端生态一、概念的理解1、脚手架2、组件 二、基础知识1、HTML2、css3、JavaScript 三、主流框架vue3框架 四、 工具(特定框架)1、uinapp 五、组件库()1、uView如何在哪项目中导入uView 六、应用(各种应…...
C#中的类
声明类 public class MyClass{ } 注意 类里面 的属性可以输入prop之后再按Tab键 然后再按Tab进行修改属性的名称等等 Random rnd new Random(); int arnd.Next(3); 范围是0-3的整数 但是不包含3 Random rnd new Random(); int arnd.Next(2,3); 只包含2一个数 int?[]…...
探索数据库编程:基础与进阶之存储函数
引言❤️❤️ 数据库存储过程是一组为了执行特定功能的SQL语句集合,它被存储在数据库中,可以通过指定存储过程的名称并给出相应的参数来调用。使用存储过程可以提高数据库操作的效率,减少网络传输量,并且可以封装复杂的逻辑。 编…...
Count数据转换为TPM数据方法整理-常规方法、DGEobj.utils和IOBR包
在正式分析之前,对于数据的处理是至关重要的,这种重要性是体现在很多方面,其中有一点是要求分析者采用正确的数据类型。 对于芯片数据,原始数据进行log2处理之后可以进行很多常见的分析,比如差异分析、热图、箱线图、…...
简易限流实现
需求描述 写一个1秒两个的限流工具类,2r/s 使用semaphore 代码实现-类似令牌桶算法 public class LimitHelper {private int maxLimit;private Semaphore semaphore;private int timeoutSeconds;public LimitHelper(int maxLimit, int timeoutSeconds) {this.max…...
用Qwt进行图表和数据可视化开发
目录 Qwt介绍 示例应用场景 典型QWT开发流程 举一些Qwt的例子,多绘制几种类型的图像 1. 绘制折线图 (Line Plot) 2. 绘制散点图 (Scatter Plot) 3. 绘制柱状图 (Bar Plot) 4. 绘制直方图 (Histogram) Qwt介绍 QWT开发主要涉及使用QWT库进行图表和数据可视化…...
sqlalchemy使用with_entities返回指定数据列
sqlalchemy使用with_entities返回指定数据列 在 SQLAlchemy 中,with_entities 方法用于指定查询语句返回的实体(Entity)或列(Column)。它允许你限制查询的返回结果,只包含你感兴趣的特定字段或实体 使用方法 假设有一个名为 User 的 SQLAlchemy 模型类,包含以下字段:…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...
【若依】框架项目部署笔记
参考【SpringBoot】【Vue】项目部署_no main manifest attribute, in springboot-0.0.1-sn-CSDN博客 多一个redis安装 准备工作: 压缩包下载:http://download.redis.io/releases 1. 上传压缩包,并进入压缩包所在目录,解压到目标…...
