#!/bin/bash # ============================================================================= # 步骤 2b:迁移后重建 Neo4j 索引(向量索引 + 全文索引 + 混合索引) # 在【迁移目标机】上执行本脚本 # 必须在 02_load_neo4j.sh 或 02_load_neo4j_by_ship.sh 之后执行 # 配置项请修改 migration_config.sh # ============================================================================= SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "${SCRIPT_DIR}/migration_config.sh" set -e INDEXING_URL="http://localhost:${DST_KGRAG_PORT}/neo4j_indexing" echo "==========================================" echo " kgrag 索引重建脚本 - 步骤 2b" echo " 接口地址: ${INDEXING_URL}" echo " Neo4j: ${NEO4J_URI}" echo "==========================================" echo "" echo "正在调用索引重建接口(可能需要几分钟)..." echo "" RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${INDEXING_URL}" \ -H "Content-Type: application/json" \ -d "{ \"neo4j_uri\": \"${NEO4J_URI}\", \"neo4j_username\": \"${NEO4J_USER}\", \"neo4j_password\": \"${NEO4J_PASSWORD}\", \"force_refresh\": true }" \ --max-time 300) HTTP_CODE=$(echo "$RESPONSE" | tail -n1) BODY=$(echo "$RESPONSE" | sed '$d') echo "HTTP 状态码: ${HTTP_CODE}" echo "返回内容: ${BODY}" if [ "$HTTP_CODE" = "409" ]; then echo " [WARN] 已有索引任务在执行(409),跳过接口调用,直接走兜底 cypher" elif [ "$HTTP_CODE" != "200" ]; then echo "" echo " [ERROR] 接口调用失败,HTTP ${HTTP_CODE}" echo " 请确认 kgrag 容器已启动,端口 ${DST_KGRAG_PORT} 可访问" exit 1 fi # 检查 hybrid_index_status(HTTP 200 但混合索引可能静默失败返回 207) HYBRID_STATUS=$(echo "$BODY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('hybrid_index_status','unknown'))" 2>/dev/null || echo "unknown") if [ "$HYBRID_STATUS" != "success" ]; then echo " [WARN] hybrid_index_status=${HYBRID_STATUS},混合索引未由接口建立,将由下方兜底命令补建" else echo " [OK] /neo4j_indexing 全部成功(含混合索引)" fi # ---------------------------------------------------------- # 补建混合索引(build_hybrid_indexes 可能静默失败,在此兜底) # 对应 neo4j_indexing.py 中 VECTOR_INDEX_NAME / FULLTEXT_INDEX_NAME / # FULLTEXT_FIELD_INDEX_NAME 三个常量 # ---------------------------------------------------------- echo "" echo "补建混合索引(global_searchable_* 系列)..." NEO4J_CONTAINER="neo4j" NEO4J_PASS="${NEO4J_PASSWORD}" docker exec "${NEO4J_CONTAINER}" cypher-shell \ -u "${NEO4J_USER}" -p "${NEO4J_PASS}" \ "CREATE VECTOR INDEX global_searchable_embedding IF NOT EXISTS FOR (n:Searchable) ON (n.embedding) OPTIONS {indexConfig: {\`vector.dimensions\`: 1024, \`vector.similarity_function\`: 'cosine'}}" docker exec "${NEO4J_CONTAINER}" cypher-shell \ -u "${NEO4J_USER}" -p "${NEO4J_PASS}" \ "CREATE FULLTEXT INDEX global_searchable_content_search IF NOT EXISTS FOR (n:Searchable) ON EACH [n.\`名称\`]" docker exec "${NEO4J_CONTAINER}" cypher-shell \ -u "${NEO4J_USER}" -p "${NEO4J_PASS}" \ "CREATE FULLTEXT INDEX global_searchable_fulltext_search IF NOT EXISTS FOR (n:Searchable) ON EACH [n.fulltext]" echo "" echo "==========================================" echo " 索引重建完成(含混合索引兜底)!" echo " 下一步:执行 python 03_update_neo4j_urls.py" echo "=========================================="