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", // 只有搜尋許可權的 key
indexUid: 'VuePressBlog',
placeholder: '支援全文搜尋', // 在搜尋欄中顯示的佔位符
maxSuggestions: 9, // 最多顯示幾個搜尋結果
cropLength: 30, // 每個搜尋結果最多顯示多少個字元
},
],
然後本地執行,試試效果:
配置 GitHub Action
如果每次更新了部落格,都重新執行建立索引的命令,也太麻煩了。我們可以指令碼化,或者使用 GitHub Action。例如,新增如下配置:
scrape-docs:
needs: test_website
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org/
- name: Run docs-scraper
env:
API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
CONFIG_FILE_PATH: ${{ github.workspace }}/docs/.vuepress/public/data/docs-scraper-config.json
run: |
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 執行情況:
(完)