一、项目概述

1.1 项目目标

开发一个基于Spring Boot + Vue 3的古诗词智能检索与推荐系统,实现诗词数据的全文检索、个性化推荐、可视化分析和系统管理功能。

1.2 已完成工作

✅ 诗词数据采集与清洗(1000首古诗词)

✅ MySQL数据库设计与数据导入

✅ Elasticsearch索引创建与数据同步

二、详细技术实现

2.1 数据采集与预处理

数据来源:从古诗词网站爬取1000首古诗词网址(古诗词网-中国最美古诗词大全

数据包含:标题、朝代、作者、内容、标签

数据格式

title,dynasty,author,content,tags
八声甘州·对潇潇暮雨洒江天,宋代,柳永,"对潇潇暮雨洒江天,一番洗清秋。渐霜风凄紧,关河冷落,残照当楼。是处红衰翠减,苒苒物华休。惟有长江水,无语东流。
不忍登高临远,望故乡渺邈,归思难收。叹年来踪迹,何事苦淹留?想佳人、妆楼颙望,误几回、天际识归舟。争知我,倚阑杆处,正恁凝愁!(阑 一作:栏)",宋词三百首; 高中古诗; 写景; 抒情; 怀人; 离情; 八声甘州
寒食,唐代,韩翃,"春城无处不飞花,寒食东风御柳斜。
日暮汉宫传蜡烛,轻烟散入五侯家。",唐诗三百首; 寒食节; 典故; 讽刺; 早教; 小学生必背古诗80首
鹊桥仙·七夕,宋代,苏轼,"缑山仙子,高清云渺,不学痴牛騃女。凤箫声断月明中,举手谢时人欲去。
客槎曾犯,银河波浪,尚带天风海雨。相逢一醉是前缘,风雨散、飘然何处?",七夕节; 月夜; 送别; 豪放; 鹊桥仙
庐山谣寄卢侍御虚舟,唐代,李白,"我本楚狂人,凤歌笑孔丘。
手持绿玉杖,朝别黄鹤楼。
五岳寻仙不辞远,一生好入名山游。
庐山秀出南斗傍,屏风九叠云锦张,
影落明湖青黛光。
金阙前开二峰长,银河倒挂三石梁,
香炉瀑布遥相望,回崖沓嶂凌苍苍。
翠影红霞映朝日,鸟飞不到吴天长。
登高壮观天地间,大江茫茫去不还。
黄云万里动风色,白波九道流雪山。
好为庐山谣,兴因庐山发。
闲窥石镜清我心,谢公行处苍苔没。
早服还丹无世情,琴心三叠道初成。
遥见仙人彩云里,手把芙蓉朝玉京。
先期汗漫九垓上,愿接卢敖游太清。",唐诗三百首; 写景; 山水; 归隐; 猖狂

数据清洗

处理中文标点符号

统一编码格式(UTF-8)

处理空值和特殊字符

标签拆分和标准化

2.2 MySQL数据库设计(8张核心表)

2.2.1 朝代表 (dynasty)
-- 1. 朝代表:存储诗词所属的历史朝代信息
CREATE TABLE `dynasty` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 朝代ID,主键,自增长
  `name` varchar(20) NOT NULL UNIQUE,           -- 朝代名称,唯一,非空
  INDEX `idx_name` (`name`)                     -- 为朝代名称创建索引,加速按名称查询
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='朝代信息';
​

作用:存储朝代信息,规范化数据

字段说明

id:朝代唯一标识

name:朝代名称(如"唐代"、"宋代")

数据示例:13个朝代(唐、宋、明、清等)

2.2.2 作者表 (author)
-- 2. 作者表:存储诗人信息,与朝代关联
CREATE TABLE `author` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 作者ID,主键,自增长
  `name` varchar(50) NOT NULL,                  -- 作者姓名,非空
  `dynasty_id` int,                             -- 所属朝代ID,外键关联朝代表
  INDEX `idx_author_name` (`name`),             -- 为作者姓名创建索引
  CONSTRAINT `fk_author_dynasty` FOREIGN KEY (`dynasty_id`) REFERENCES `dynasty` (`id`) ON DELETE SET NULL
  -- 外键约束:关联朝代表,当朝代被删除时,将作者表的dynasty_id设为NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='作者信息';
​

作用:存储诗人信息,关联朝代

字段说明

id:作者唯一标识

name:作者姓名

dynasty_id:所属朝代ID(外键)

数据示例:289位作者(李白、杜甫、苏轼等)

2.2.3 诗词表 (poetry) - 核心表
-- 3. 诗词表(核心表):存储诗词的详细信息
CREATE TABLE `poetry` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 诗词ID,主键,自增长
  `title` varchar(200) NOT NULL,                -- 诗词标题,非空
  `content` text NOT NULL,                      -- 诗词全文,非空
  `author_id` int NOT NULL,                     -- 作者ID,外键关联作者表
  `dynasty_id` int NOT NULL,                    -- 朝代ID,外键关联朝代表
  `tags_raw` varchar(500) DEFAULT NULL COMMENT '原始标签字符串,用于ES同步',  -- 标签字符串,用于同步到Elasticsearch
  `content_hash` char(32) NOT NULL COMMENT 'MD5去重',  -- 诗词内容的MD5哈希值,用于内容去重
  `es_sync_status` tinyint DEFAULT 0 COMMENT '0-未同步,1-已同步',  -- 同步到Elasticsearch的状态
  `favorite_count` int DEFAULT 0 COMMENT '收藏次数',  -- 被用户收藏的次数
  `view_count` int DEFAULT 0 COMMENT '浏览次数',      -- 被用户查看的次数
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,  -- 记录创建时间
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  -- 记录最后更新时间
  UNIQUE KEY `uk_content_hash` (`content_hash`),    -- 唯一约束,确保内容不重复
  INDEX `idx_title` (`title`(20)),               -- 对标题前20个字符创建索引,优化标题搜索
  INDEX `idx_author_id` (`author_id`),           -- 作者ID索引
  INDEX `idx_dynasty_id` (`dynasty_id`),          -- 朝代ID索引
  INDEX `idx_es_sync` (`es_sync_status`),        -- 同步状态索引
  CONSTRAINT `fk_poetry_author` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`) ON DELETE CASCADE,
  -- 外键约束:关联作者表,级联删除(作者删除时,其诗词也删除)
  CONSTRAINT `fk_poetry_dynasty` FOREIGN KEY (`dynasty_id`) REFERENCES `dynasty` (`id`) ON DELETE CASCADE
  -- 外键约束:关联朝代表,级联删除(朝代删除时,其诗词也删除)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='诗词信息';
​

作用:存储诗词核心信息

关键字段

content_hash:MD5(title+author+dynasty+content),防止重复导入

es_sync_status:标记是否已同步到Elasticsearch

tags_raw:保留原始标签字符串,便于调试和ES同步

数据示例:1000首诗词

2.2.4 标签表 (tag)
-- 4. 标签表:存储诗词标签,用于分类和检索
CREATE TABLE `tag` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 标签ID,主键,自增长
  `name` varchar(50) NOT NULL UNIQUE,           -- 标签名称,唯一,非空
  INDEX `idx_tag_name` (`name`)                 -- 标签名称索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='标签信息';
​

作用:存储诗词分类标签

数据示例:498个标签(思乡、山水、爱情、边塞等)

2.2.5 诗词标签关联表 (poetry_tag)
-- 5. 诗词标签关联表:多对多关系,记录诗词与标签的对应关系
CREATE TABLE `poetry_tag` (
  `poetry_id` int NOT NULL,                     -- 诗词ID
  `tag_id` int NOT NULL,                        -- 标签ID
  PRIMARY KEY (`poetry_id`, `tag_id`),          -- 联合主键,防止重复关联
  INDEX `idx_tag_id` (`tag_id`),                -- 标签ID索引,方便通过标签查找诗词
  CONSTRAINT `fk_poetry_tag_poetry` FOREIGN KEY (`poetry_id`) REFERENCES `poetry` (`id`) ON DELETE CASCADE,
  -- 外键约束:关联诗词表,级联删除
  CONSTRAINT `fk_poetry_tag_tag` FOREIGN KEY (`tag_id`) REFERENCES `tag` (`id`) ON DELETE CASCADE
  -- 外键约束:关联标签表,级联删除
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='诗词标签关联';

作用:实现诗词和标签的多对多关系

数据示例:4215条关联记录

2.2.6 用户表 (user)
-- 6. 用户表:存储系统用户信息
CREATE TABLE `user` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 用户ID,主键,自增长
  `username` varchar(50) NOT NULL UNIQUE,       -- 用户名,唯一,非空
  `password` varchar(255) NOT NULL,             -- 密码(加密存储)
  `email` varchar(100) UNIQUE,                  -- 邮箱,唯一
  `nickname` varchar(50) DEFAULT NULL,          -- 昵称
  `role` varchar(20) DEFAULT 'USER' COMMENT 'ADMIN-管理员,USER-普通用户',  -- 用户角色
  `status` tinyint DEFAULT 1 COMMENT '0-禁用,1-正常',  -- 用户状态
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,  -- 注册时间
  `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  -- 最后更新时间
  INDEX `idx_username` (`username`),            -- 用户名索引
  INDEX `idx_role` (`role`)                     -- 角色索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户信息';

作用:存储系统用户信息

角色设计

ADMIN:管理员,可管理所有内容

USER:普通用户,可浏览、搜索、收藏

测试数据:创建了3个测试用户(admin, user1, user2)

2.2.7 用户收藏表 (user_favorite)
-- 7. 用户收藏表:记录用户收藏的诗词
CREATE TABLE `user_favorite` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 收藏记录ID,主键,自增长
  `user_id` int NOT NULL,                       -- 用户ID
  `poetry_id` int NOT NULL,                     -- 诗词ID
  `created_at` datetime DEFAULT CURRENT_TIMESTAMP,  -- 收藏时间
  UNIQUE KEY `uk_user_poetry` (`user_id`, `poetry_id`),  -- 唯一约束,防止用户重复收藏同一诗词
  INDEX `idx_user_id` (`user_id`),              -- 用户ID索引,方便查询用户的收藏
  INDEX `idx_poetry_id` (`poetry_id`),          -- 诗词ID索引,方便查询诗词的被收藏情况
  CONSTRAINT `fk_user_favorite_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE,
  -- 外键约束:关联用户表,级联删除
  CONSTRAINT `fk_user_favorite_poetry` FOREIGN KEY (`poetry_id`) REFERENCES `poetry` (`id`) ON DELETE CASCADE
  -- 外键约束:关联诗词表,级联删除
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户收藏记录';
​

作用:记录用户收藏的诗词,用于个性化推荐

数据示例:目前为空,等待用户操作

2.2.8 搜索日志表 (search_log)
-- 8. 搜索日志表:记录用户的搜索关键词,用于热门搜索分析
CREATE TABLE `search_log` (
  `id` int PRIMARY KEY AUTO_INCREMENT,          -- 日志ID,主键,自增长
  `keyword` varchar(200) NOT NULL,              -- 搜索关键词
  `search_count` int DEFAULT 1,                 -- 搜索次数,默认1
  `last_search_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  -- 最后搜索时间
  UNIQUE KEY `uk_keyword` (`keyword`),          -- 唯一约束,每个关键词只保留一条记录,通过search_count累计
  INDEX `idx_search_count` (`search_count`),    -- 搜索次数索引,用于排序热门关键词
  INDEX `idx_last_search_time` (`last_search_time`)  -- 最后搜索时间索引,用于近期热门
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='搜索日志';
​
show tables ;
​

作用:记录热门搜索词,用于搜索热词分析和可视化

数据示例:目前为空,等待用户搜索

2.3 数据库关系设计理念

规范化设计

第一范式:每个字段都是原子性的

第二范式:消除部分依赖

第三范式:消除传递依赖

外键关系

poetry.author_idauthor.id

poetry.dynasty_iddynasty.id

poetry_tag.poetry_idpoetry.id

poetry_tag.tag_idtag.id

user_favorite.user_iduser.id

user_favorite.poetry_idpoetry.id

索引设计

主键索引:所有表

唯一索引:用户名、邮箱、朝代名、标签名

外键索引:所有外键字段

复合索引:用户收藏表的(user_id, poetry_id)

2.4 数据导入过程

Python导入脚本关键功能

# 1. 读取CSV文件
df = pd.read_csv('poems_with_tags.csv', encoding='utf-8', dtype=object)
​
# 2. 数据清洗
def clean_text(text):
    # 处理空值、特殊字符、换行符
    pass
​
# 3. 去重机制
content_hash = hashlib.md5(f"{title}|{author}|{dynasty}|{content}".encode()).hexdigest()
​
# 4. 分步导入
# 第一步:导入朝代
# 第二步:导入作者(关联朝代)
# 第三步:导入诗词(关联作者和朝代)
# 第四步:导入标签和关联关系

导入统计结果

朝代:13个

作者:289位

诗词:1000首

标签:498个

诗词-标签关联:4215条

用户:3个(admin, user1, user2)

2.5 Elasticsearch索引设计与数据同步

2.5.1 Elasticsearch索引创建

索引名称poetry_index

索引设置

{
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 0,
    "analysis": {
      "analyzer": {
        "chinese_analyzer": {
          "type": "custom",
          "tokenizer": "ik_max_word",
          "char_filter": ["html_strip"],
          "filter": ["lowercase"]
        },
        "chinese_smart_analyzer": {
          "type": "custom",
          "tokenizer": "ik_smart",
          "char_filter": ["html_strip"],
          "filter": ["lowercase"]
        }
      }
    }
  }
}

映射设计

{
  "mappings": {
    "properties": {
      "id": {"type": "keyword"},
      "title": {
        "type": "text",
        "analyzer": "chinese_analyzer",
        "search_analyzer": "chinese_smart_analyzer",
        "fields": {
          "keyword": {"type": "keyword"}
        }
      },
      "content": {
        "type": "text", 
        "analyzer": "chinese_analyzer",
        "search_analyzer": "chinese_smart_analyzer"
      },
      "authorId": {"type": "integer"},
      "authorName": {
        "type": "keyword",
        "fields": {
          "text": {"type": "text", "analyzer": "chinese_analyzer"}
        }
      },
      "dynastyId": {"type": "integer"},
      "dynastyName": {"type": "keyword"},
      "tags": {
        "type": "keyword",
        "fields": {
          "text": {"type": "text", "analyzer": "chinese_analyzer"}
        }
      },
      "tagsRaw": {"type": "keyword"},
      "favoriteCount": {"type": "integer"},
      "viewCount": {"type": "integer"},
      "createdAt": {"type": "date"},
      "updatedAt": {"type": "date"}
    }
  }
}

分词器配置

IK分词器:处理中文分词

ik_max_word:最细粒度分词(索引时使用)

ik_smart:智能分词(搜索时使用)

多字段类型:支持精确匹配和模糊搜索

停用词过滤:过滤无意义词汇

class PoetrySyncManager:
    def __init__(self):
        # MySQL配置
        self.mysql_config = {
            'host': 'localhost',
            'user': 'root',
            'password': '045713', 
            'database': 'poetry_db',
            'charset': 'utf8mb4',
            'cursorclass': pymysql.cursors.DictCursor
        }
​
        # Elasticsearch配置
        self.es_config = {
            'hosts': ['http://localhost:9200'],
            'timeout': 30
        }
​
        # 连接池
        self.mysql_conn = None
        self.es_client = None
​
    def connect_mysql(self):
        """连接MySQL数据库"""
        try:
            self.mysql_conn = pymysql.connect(**self.mysql_config)
            print(" MySQL连接成功")
            return True
        except Exception as e:
            print(f" MySQL连接失败: {e}")
            return False
​
    def connect_elasticsearch(self):
        """连接Elasticsearch"""
        try:
            self.es_client = Elasticsearch(**self.es_config)
            if self.es_client.ping():
                print("Elasticsearch连接成功")
                return True
            else:
                print("Elasticsearch连接失败")
                return False
        except Exception as e:
            print(f" Elasticsearch连接失败: {e}")
            return False

2.5.2 MySQL与Elasticsearch数据映射关系

一对一映射

MySQL表字段             →     ES文档字段
-----------------------------------------------
poetry.id               →     id (keyword)
poetry.title            →     title (text)
poetry.content          →     content (text)
poetry.favorite_count   →     favoriteCount (integer)
poetry.view_count       →     viewCount (integer)
poetry.created_at       →     createdAt (date)
poetry.updated_at       →     updatedAt (date)
poetry.tags_raw         →     tagsRaw (keyword)

多对一映射(反规范化)

MySQL多表关联查询结果     →     ES单个文档
-----------------------------------------------
author.id               →     authorId (integer)
author.name             →     authorName (keyword + text)
dynasty.id              →     dynastyId (integer)  
dynasty.name            →     dynastyName (keyword)
tag.name (多行)         →     tags (keyword数组)

反规范化设计的好处

查询性能:避免ES中的JOIN操作

搜索效率:一次查询返回完整信息

简化架构:降低系统复杂度

2.5.3 同步验证结果

同步统计

总诗词数量:1000首

成功同步:1000首

同步失败:0首

ES文档总数:1000个

搜索测试结果

搜索"明月":找到53条结果 ✓

搜索"李白":找到53条结果 ✓

2.6 技术栈配置详情

2.6.1 后端技术栈

Spring Boot 2.7.x:基础框架

Spring Data JPA:MySQL ORM

Spring Data Elasticsearch:ES客户端

Spring Security + JWT:安全认证

Spring Scheduler:定时任务

Redis:缓存(待配置)

2.6.2 前端技术栈

Vue 3.0:前端框架

Element Plus:UI组件库

Axios:HTTP客户端

Vue Router 4:路由管理

Pinia:状态管理

ECharts 5.x:数据可视化

2.6.3 数据库技术栈

MySQL 8.0:关系型数据库

Elasticsearch 8.x:搜索引擎

Redis 6.0:缓存数据库

IK Analysis:中文分词器

2.6.4 开发环境

操作系统:Windows 11

开发工具:IntelliJ IDEA , PyCharm

版本控制:Git 2.40

Java版本:JDK 8

Python版本:3.11(用于数据导入脚本)

2.7 系统架构设计

2.7.1 整体架构
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   前端Vue 3     │    │   Spring Boot   │    │     数据库层    │
│   (用户界面)    │◄──►│   (业务逻辑)    │◄──►│ MySQL + ES + Redis
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │
         │                       │                       │
    HTTP/JSON             服务调用/事务              数据持久化/检索
2.7.2 数据流架构
CSV数据
         │
         ▼
   数据清洗脚本 (Python)
         │
         ▼
     MySQL数据库
         │
         ├──────────────┐
         ▼              ▼
   业务查询        同步脚本
         │              │
         ▼              ▼
   业务响应    Elasticsearch
         │              │
         └──────┬───────┘
                ▼
           前端展示
2.7.3 搜索架构
用户搜索请求
     │
     ▼
  Spring Controller
     │
     ▼
  PoetryService
     │
     ▼
ElasticsearchRepository
     │
     ▼
Elasticsearch集群
     │
     ▼
 搜索结果处理
     │
     ▼
 返回JSON结果

2.8 已实现的核心功能模块

2.8.1 数据管理模块

✅ 数据采集与清洗

✅ 数据库设计与创建

✅ 数据导入与验证

✅ ES索引创建与同步

2.8.2 搜索基础模块

✅ 全文检索索引设计

✅ 中文分词器配置

✅ 基础搜索测试

2.9 项目特色与创新点

双数据库架构:MySQL负责事务和关联查询,ES负责全文检索

反规范化设计:ES中存储冗余信息,优化搜索性能

中文分词优化:IK分词器支持诗词特殊词汇

可扩展设计:模块化设计,便于功能扩展

2.10 下一步开发计划

阶段一:Spring Boot后端开发
阶段二:Vue 3前端开发
阶段三:高级功能开发(数据可视化,个性化推荐算法)

2.11 关键技术难点与解决方案

难点1:中文分词准确性

问题:古诗词有特殊词汇和句式

解决方案:使用IK分词器,配置自定义词典

难点2:搜索性能

问题:大量数据全文检索

解决方案:ES倒排索引+合理分片+缓存策略

难点4:系统安全性

问题:用户数据和系统安全

解决方案:Spring Security + JWT + 参数校验

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐