Misskey Meilisearch索引之前的旧内容 记录
1.导出帖子数据
首先,进入PostgreSQL的Docker容器,并导出帖子列表。使用以下命令:
sudo docker compose exec -it db /bin/bash
psql -U username -d misskey -c "SELECT json_agg(row_to_json(t)) ::text FROM (SELECT id, \"userId\", \"userHost\", \"channelId\", cw, text, tags, \"attachedFileTypes\" FROM note WHERE visibility IN ('home', 'public') LIMIT 100000) t" > /var/lib/postgresql/data/notes_tmp
exit
如果指定范围可以添加where
psql -U username -d misskey -c "SELECT json_agg(row_to_json(t)) ::text FROM (SELECT id, \"userId\", \"userHost\", \"channelId\", cw, text, tags, \"attachedFileTypes\" FROM note WHERE visibility IN ('home', 'public') AND id < 'ab4fhvt5qacu0001' AND id > 'a169ymm9q9by02qo' LIMIT 100000) t" > /var/lib/postgresql/data/notes_tmp
在这里,替换username和misskey为你的POSTGRES_USER和POSTGRES_DB的实际值。
2.转换数据格式为JSON:
将导出的数据转换为JSON格式,为导入MeiliSearch做准备。首先安装jq,然后使用sed和jq来处理文件。
sudo apt install jq
sudo sed -i '1d;2d;x;$d;' ./notes_tmp
使用以下process_notes.sh脚本,为notes_tmp添加createdAt字段
#!/bin/bash
# Base36解码函数:将base36字符串转换为十进制数
base36decode() {
local s="$1"
local num=0
local len=${#s}
for (( i=0; i<len; i++ )); do
c=${s:i:1}
# 处理数字字符
if [[ $c =~ [0-9] ]]; then
val=$((10#$c))
# 处理小写字母字符
elif [[ $c =~ [a-z] ]]; then
val=$(( $(printf "%d" "'$c") - $(printf "%d" "'a") + 10 ))
# 处理大写字母字符
elif [[ $c =~ [A-Z] ]]; then
val=$(( $(printf "%d" "'$c") - $(printf "%d" "'A") + 10 ))
else
echo "错误:无效的base36字符 '$c'" >&2
return 1
fi
num=$(( num * 36 + val ))
done
echo "$num"
}
# 解析aidx为包含毫秒的纯数字时间戳(格式如1728923182658)
parseAid() {
local aidx="$1"
# 检查输入参数
if [ -z "$aidx" ]; then
echo "错误:请提供aidx参数" >&2
return 1
fi
# 提取前8个字符作为base36时间部分
local base36_time="${aidx:0:8}"
# 解码base36时间为毫秒数
local ms=$(base36decode "$base36_time")
if [ $? -ne 0 ]; then
return 1
fi
# 计算总毫秒数(基准时间的毫秒数 + 解码得到的毫秒数)
# 基准时间946684800秒 = 946684800000毫秒
local total_ms=$((946684800 * 1000 + ms))
echo "$total_ms"
}
# 检查输入文件是否存在
if [ ! -f "./notes_tmp" ]; then
echo "错误:notes_tmp文件不存在" >&2
exit 1
fi
# 临时文件用于存储处理后的JSON对象
temp_file=$(mktemp)
# 处理每个JSON对象
total=$(jq '. | length' ./notes_tmp)
count=0
first_item=true
echo "开始处理,共$total条记录..."
jq -c '.[]' ./notes_tmp | while read -r item; do
((count++))
# 提取id字段
id=$(echo "$item" | jq -r '.id')
if [ "$id" = "null" ] || [ -z "$id" ]; then
echo "警告:第$count条记录缺少id,跳过处理" >&2
processed_item="$item"
else
# 解析id获取时间戳
createdAt=$(parseAid "$id")
if [ $? -ne 0 ]; then
echo "警告:第$count条记录id=$id解析失败,跳过处理" >&2
processed_item="$item"
else
# 添加createdAt字段
processed_item=$(echo "$item" | jq --arg ca "$createdAt" '. + {createdAt: $ca}')
fi
fi
# 正确处理逗号分隔
if [ "$first_item" = true ]; then
echo "$processed_item" >> "$temp_file"
first_item=false
else
echo ",$processed_item" >> "$temp_file"
fi
# 显示进度
if (( count % 100 == 0 )); then
echo "已处理$count/$total条记录"
fi
done
# 组合成完整的JSON数组
{
echo "["
cat "$temp_file"
echo "]"
} > ./notes_with_createdAt.json
# 清理临时文件
rm "$temp_file"
echo "处理完成,结果已保存到notes_with_createdAt.json"
echo "总处理记录:$total"
3.导入数据到MeiliSearch:
sudo docker compose exec -it meilisearch /bin/ash
curl -X POST 'http://localhost:7700/indexes/your_index_name---notes/documents' --data @/meili_data/notes_with_createdAt.json -H 'Content-Type: application/json' -H "Authorization: Bearer your_master_key"
exit
在这里,your_index_name替换为你的MeiliSearch索引名称,your_master_key替换为你的MeiliSearch API密钥。
也可以使用meilisearch-ui上传导入json。