這之前是手動將資料灌到 Typesense 中建立索引,但應該要在網站有新增資料時動態同步索引,目前用的是 Directus 作為 CMS ,所以要在 Directus 中自建一個 directus extension 來做同步。
首先在 Directus 目錄底下的 extensions 中創建插件。
cd extensions
npx create-directus-extension@latest
extension 類別選擇 hook
然後取名 typesense-indexing
然後啟動開發模式。
npm run dev
為了方便開發,Directus 的 .env
中加上 EXTENSIONS_AUTO_RELOAD="true"
,讓 Directus 在 extensions 資料夾裡有更新的話就會自動重載插件。
插件的撰寫主要在 index 檔案上。
// extensions/typesense-indexing/src/index.ts
import { defineHook } from "@directus/extensions-sdk";
import Typesense from "typesense";
const typesense = new Typesense.Client({
nodes: [
{
host: process.env.TYPESENSE_HOST || "localhost",
port: process.env.TYPESENSE_PORT || "8108",
protocol: process.env.TYPESENSE_PROTOCOL || "http",
},
],
apiKey: process.env.TYPESENSE_KEY || "xyz",
numRetries: 3, // A total of 4 tries (1 original try + 3 retries)
connectionTimeoutSeconds: 10,
logLevel: "debug",
});
export default defineHook(({ filter, action }) => {
action("posts.items.create", async (meta) => {
await typesense
.collections("posts")
.documents()
.create({
...meta.payload,
id: meta.key,
date_created: new Date().getTime(),
});
});
});
另外也不能忘了在 Typesense 先建好 Collection。
curl "${TYPESENSE_HOST}/collections" \
-X POST \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
"name": "posts",
"fields": [
{ "name": "title", "type": "string" },
{ "name": "content", "type": "string" },
{ "name": "date_created", "type": "int32" }
],
"default_sorting_field": "date_created"
}'
都設定好後就能在 Directus 這邊嘗試新建 Posts 資料,看看 Typesense 這邊的同步結果了。