刘明野

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

[https://paopaoshequ.com/notes/ab4ulujlzqs60004]()

本文为作者刘明野发布,未经允许禁止转载!
8
0
0
发表留言

友情链接