为 Misskey 开启 Meilisearch 后,重新索引过去的帖子

一篇简短的笔记,为 Misskey 开启 Meilisearch 后,重新索引过去的帖子。

首先编写这样一个 SQL 文件

SELECT json_agg(row_to_json(n.*)) FROM (
SELECT "id", "userId", "channelId", "cw", "text", "tags"
FROM "note"
WHERE ("note"."visibility" = 'public' OR "note"."visibility" = 'home') AND
("note"."text" IS NOT NULL) AND
("note"."uri" IS NULL)
ORDER BY id desc
) n

我们不妨保存它为 get_notes.sql

这个 SQL 的意思很显然,就是从帖子表中找到 publichome 可见性的本地帖子 (uri is null) 并输出成 JSON

然后执行它,得到一个 notes.json

psql -d {your_db_name} -t -f get_notes.sql > notes.json

然后创建一个 send_notes.mjs。最前方的 config 请用你的 misskey 的 .config/default.yml 内关于 Meilisearch 的部分替换。

import fs from "fs";

const config = {
"ms_url": "http://127.0.0.1:7700",
"api_key": "YOUR_API_KEY",
"index": "YOUR_INDEX"
}

const headers = {
"Content-Type": "application/json",
"Authorization": `Bearer ${config.api_key}`
}

/** @typedef {{id: string, userId: string, channelId: string, cw: string | null, text: string, tags: string[]}} {Note} */

/** @type {Note[]} */
const notes = JSON.parse(fs.readFileSync("notes.json"));

/**
* @see https://github.com/misskey-dev/misskey/blob/4b295088fd6b4bead05087537415b10419eee78f/packages/backend/src/misc/id/aid.ts#L34
*/
function parseAid(id) {
const TIME2000 = 946684800000;
const time = parseInt(id.slice(0, 8), 36) + TIME2000;
return time;
}

for (const note of notes) {
note.createdAt = parseAid(note.id);
note.userHost = null;
}

console.log("Reindexing", notes.length, "notes");

fetch(config.ms_url + `/indexes/${config.index}---notes/documents?primaryKey=id`, {
method: "POST",
headers,
body: JSON.stringify(notes),
}).then((res) => res.text())
.then(text => {
console.log(text);
});

执行 node send_note.mjs, 如果成功把帖子送给了 Meilisearch 进行索引,我们应该能看到像这样的输出内容:

{"taskUid":9241,"indexUid":"shonk_social---notes","status":"enqueued","type":"documentAdditionOrUpdate","enqueuedAt":"2024-09-07T06:31:44.177026811Z"}

如果要查看索引进度,记下 taskUid。使用像这样命令就可以查看索引进度了:

curl -s 'http://localhost:7700/tasks/{taskUid}' -H "Authorization: Bearer {your_api_key}" | jq .