/** * 初始化价值论坛 Elasticsearch 索引 * 运行方式:node init-forum-es.js */ const axios = require('axios'); // Elasticsearch 配置 const ES_BASE_URL = 'http://222.128.1.157:19200'; // 创建 axios 实例 const esClient = axios.create({ baseURL: ES_BASE_URL, timeout: 10000, headers: { 'Content-Type': 'application/json', }, }); // 索引名称 const INDICES = { POSTS: 'forum_posts', COMMENTS: 'forum_comments', EVENTS: 'forum_events', }; async function initializeIndices() { try { console.log('开始初始化 Elasticsearch 索引...\n'); // 1. 创建帖子索引 console.log('创建帖子索引 (forum_posts)...'); try { await esClient.put(`/${INDICES.POSTS}`, { mappings: { properties: { id: { type: 'keyword' }, author_id: { type: 'keyword' }, author_name: { type: 'text' }, author_avatar: { type: 'keyword' }, title: { type: 'text' }, content: { type: 'text' }, images: { type: 'keyword' }, tags: { type: 'keyword' }, category: { type: 'keyword' }, likes_count: { type: 'integer' }, comments_count: { type: 'integer' }, views_count: { type: 'integer' }, created_at: { type: 'date' }, updated_at: { type: 'date' }, is_pinned: { type: 'boolean' }, status: { type: 'keyword' }, }, }, }); console.log('✅ 帖子索引创建成功\n'); } catch (error) { if (error.response?.status === 400 && error.response?.data?.error?.type === 'resource_already_exists_exception') { console.log('⚠️ 帖子索引已存在,跳过创建\n'); } else { throw error; } } // 2. 创建评论索引 console.log('创建评论索引 (forum_comments)...'); try { await esClient.put(`/${INDICES.COMMENTS}`, { mappings: { properties: { id: { type: 'keyword' }, post_id: { type: 'keyword' }, author_id: { type: 'keyword' }, author_name: { type: 'text' }, author_avatar: { type: 'keyword' }, content: { type: 'text' }, parent_id: { type: 'keyword' }, likes_count: { type: 'integer' }, created_at: { type: 'date' }, status: { type: 'keyword' }, }, }, }); console.log('✅ 评论索引创建成功\n'); } catch (error) { if (error.response?.status === 400 && error.response?.data?.error?.type === 'resource_already_exists_exception') { console.log('⚠️ 评论索引已存在,跳过创建\n'); } else { throw error; } } // 3. 创建事件时间轴索引 console.log('创建事件时间轴索引 (forum_events)...'); try { await esClient.put(`/${INDICES.EVENTS}`, { mappings: { properties: { id: { type: 'keyword' }, post_id: { type: 'keyword' }, event_type: { type: 'keyword' }, title: { type: 'text' }, description: { type: 'text' }, source: { type: 'keyword' }, source_url: { type: 'keyword' }, related_stocks: { type: 'keyword' }, occurred_at: { type: 'date' }, created_at: { type: 'date' }, importance: { type: 'keyword' }, }, }, }); console.log('✅ 事件时间轴索引创建成功\n'); } catch (error) { if (error.response?.status === 400 && error.response?.data?.error?.type === 'resource_already_exists_exception') { console.log('⚠️ 事件时间轴索引已存在,跳过创建\n'); } else { throw error; } } // 4. 验证索引 console.log('验证索引...'); const indices = await esClient.get('/_cat/indices/forum_*?v&format=json'); console.log('已创建的论坛索引:'); indices.data.forEach(index => { console.log(` - ${index.index} (docs: ${index['docs.count']}, size: ${index['store.size']})`); }); console.log('\n🎉 所有索引初始化完成!'); console.log('\n下一步:'); console.log('1. 访问 https://valuefrontier.cn/value-forum'); console.log('2. 点击"发布帖子"按钮创建第一篇帖子'); } catch (error) { console.error('❌ 初始化失败:', error.message); if (error.response) { console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); } process.exit(1); } } // 执行初始化 initializeIndices();