Skip to content
chenhhhpppPublic

About

基于 Elasticsearch 一站式聚合搜索平台

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

🔍 Allso 聚合搜索平台

一站式聚合搜索 · 多数据源并发检索 · Elasticsearch 全文检索

Vue 3 + Spring Boot + Elasticsearch + Redis 全栈项目


📖 项目简介

Allso 是一个聚合搜索平台,支持用户在一个入口同时搜索 文章、图片、用户 三类数据源。项目采用前后端分离架构,后端通过 数据源注册机制 + CompletableFuture 并发查询 实现可扩展的聚合搜索,使用 Elasticsearch + IK 中文分词 实现文章全文检索,并支持 全量同步 + 增量同步 + Canal binlog 三种数据同步模式。

✨ 核心特性

特性 说明
🚀 多数据源聚合搜索 一次请求并发检索文章、图片、用户,毫秒级响应
🔎 Elasticsearch 全文检索 IK 中文分词,支持标题、内容、标签多字段组合查询
🧩 数据源注册机制 策略模式 + 注册表模式,新增数据源零侵入扩展
⚡ CompletableFuture 并发 全类型搜索时多数据源并行执行,大幅降低响应时间
🔄 多模式数据同步 全量同步(启动时)+ 增量同步(定时任务)+ Canal binlog(预留)
🛡️ 完善的权限体系 自定义 @AuthCheck 注解 + AOP 拦截,支持用户/管理员角色
📦 腾讯云 COS 集成 图片/文件上传至对象存储,支持业务隔离
🎨 响应式前端界面 Vue 3 + Ant Design Vue,紫蓝渐变现代风格

✨ 页面展示

image image image image image image image

🛠️ 技术栈

后端

技术 版本 用途
Spring Boot 2.7.2 核心框架
Spring Data Elasticsearch - 全文检索
MyBatis-Plus 3.5.2 增强 ORM
Spring Data Redis - 缓存 / 分布式 Session
MySQL 8.x 关系型数据库
Elasticsearch 7.17.25 搜索引擎
Knife4j 3.0.3 API 接口文档
腾讯云 COS SDK 5.6.89 对象存储
Jsoup 1.15.3 网页爬虫(图片搜索)
Hutool 5.8.8 Java 工具库
EasyExcel 3.1.1 Excel 导入导出
Canal Client 1.1.0 MySQL binlog 同步

前端

技术 版本 用途
Vue.js ^3.2.13 核心框架
Ant Design Vue ^3.3.0-beta.4 UI 组件库
Vue Router ^4.0.3 路由管理
Axios ^1.3.4 HTTP 请求
TypeScript ~4.5.5 类型系统
Vue CLI ~5.0.0 构建工具链

🏗️ 系统架构

flowchart TB
    subgraph Frontend["🎨 前端 (Vue 3 + Ant Design Vue)"]
        UI[搜索页面 IndexPage]
        UI -->|分类切换| Tab[文章 / 图片 / 用户]
    end

    subgraph Backend["⚙️ 后端 (Spring Boot)"]
        API[SearchController<br/>聚合搜索入口]
        Facade[SearchFacade<br/>门面模式]
        Registry[DataSourceRegistry<br/>数据源注册表]

        subgraph DataSources["数据源层 (策略模式)"]
            DS1[PostDataSource<br/>→ Elasticsearch]
            DS2[UserDataSource<br/>→ MySQL]
            DS3[PictureDataSource<br/>→ 必应爬虫]
        end

        API --> Facade
        Facade -->|CompletableFuture 并发| Registry
        Registry --> DataSources
    end

    subgraph Storage["💾 数据层"]
        ES[(Elasticsearch<br/>全文检索)]
        DB[(MySQL<br/>业务数据)]
        Redis[(Redis<br/>Session缓存)]
        Bing[必应图片<br/>外部爬取]
    end

    DS1 --> ES
    DS2 --> DB
    DS3 --> Bing
    Backend <-->|Session| Redis

    Frontend -->|HTTP API| API
    ES -.->|双向同步| DB

    style Frontend fill:#e6f7ff,stroke:#1890ff
    style Backend fill:#f6ffed,stroke:#52c41a
    style Storage fill:#fff7e6,stroke:#fa8c16
Loading

📂 项目结构

Allso/
├── src/main/java/com/chp/allso/          # 后端源码
│   ├── annotation/                        # 自定义注解
│   │   └── AuthCheck.java                 #   权限校验注解
│   ├── aop/                               # 切面编程
│   │   ├── AuthInterceptor.java           #   权限拦截器
│   │   └── LogInterceptor.java            #   日志拦截器
│   ├── controller/                        # 控制层
│   │   ├── SearchController.java          #   🔑 聚合搜索入口
│   │   ├── PostController.java            #   文章接口
│   │   ├── UserController.java            #   用户接口
│   │   ├── PictureController.java         #   图片接口
│   │   └── FileController.java            #   文件上传
│   ├── datasource/                        # 🔑 数据源注册机制
│   │   ├── DataSource.java                #   统一接口
│   │   ├── DataSourceRegistry.java        #   注册表
│   │   ├── PostDataSource.java            #   ES 文章源
│   │   ├── UserDataSource.java            #   MySQL 用户源
│   │   └── PictureDataSource.java         #   必应图片源
│   ├── esdao/                             # Elasticsearch 数据访问层
│   ├── manager/                           # 管理层(门面模式)
│   │   └── SearchFacade.java              #   🔑 搜索门面
│   ├── service/                           # 业务逻辑层
│   ├── mapper/                            # MyBatis 数据访问
│   ├── model/                             # 数据模型
│   │   ├── entity/                        #   数据库实体
│   │   ├── dto/                           #   数据传输对象
│   │   └── vo/                            #   视图对象
│   ├── job/                               # 定时任务 / 数据同步
│   │   ├── cycle/IncSyncPostToEs.java     #   增量同步
│   │   └── once/FullSyncPostToEs.java     #   全量同步
│   └── config/                            # 配置类
│
├── allso-frontend/                        # 前端源码
│   └── src/
│       ├── pages/IndexPage.vue            # 🔑 搜索主页
│       ├── components/                    # 业务组件
│       │   ├── PostList.vue               #   文章列表
│       │   ├── PictureList.vue            #   图片列表
│       │   └── UserList.vue               #   用户列表
│       ├── plugins/myAxios.ts             #   Axios 封装
│       └── router/index.ts                #   路由配置
│
├── sql/                                   # SQL 脚本
│   ├── create_table.sql                   #   建表语句
│   └── post_es_mapping.json               #   ES 索引映射
├── Dockerfile                             # Docker 部署
└── pom.xml                                # Maven 依赖

🔑 标记为核心文件


💾 数据库设计

ER 关系图

erDiagram
    USER ||--o{ POST : "发布"
    USER ||--o{ POST_THUMB : "点赞"
    USER ||--o{ POST_FAVOUR : "收藏"
    POST ||--o{ POST_THUMB : "被点赞"
    POST ||--o{ POST_FAVOUR : "被收藏"

    USER {
        bigint id PK
        varchar userAccount "登录账号"
        varchar userPassword "MD5加密"
        varchar userName "昵称"
        varchar userAvatar "头像"
        varchar userProfile "简介"
        varchar userRole "user/admin/ban"
        datetime createTime
        datetime updateTime
        tinyint isDelete "逻辑删除"
    }

    POST {
        bigint id PK
        varchar title "标题"
        text content "内容"
        varchar tags "标签JSON"
        int thumbNum "点赞数"
        int favourNum "收藏数"
        bigint userId "作者ID"
        datetime createTime
        datetime updateTime
        tinyint isDelete "逻辑删除"
    }

    POST_THUMB {
        bigint id PK
        bigint postId "帖子ID"
        bigint userId "用户ID"
        datetime createTime
    }

    POST_FAVOUR {
        bigint id PK
        bigint postId "帖子ID"
        bigint userId "用户ID"
        datetime createTime
    }
Loading

MySQL ↔ Elasticsearch 映射

MySQL post 表 Elasticsearch post 索引 说明
id (bigint) id (long) 主键
title (varchar) title (text · ik_max_word) 标题,中文分词
content (text) content (text · ik_max_word) 内容,中文分词
tags (varchar JSON) tags (List<String>) 标签,DB为字符串/ES为数组
userId (bigint) userId (keyword) 作者ID
createTime (datetime) createTime (date) 创建时间
thumbNum / favourNum — 仅存 MySQL,查询时回查

🔑 核心流程

聚合搜索流程

sequenceDiagram
    participant U as 用户
    participant F as 前端 IndexPage
    participant C as SearchController
    participant SF as SearchFacade
    participant R as DataSourceRegistry
    participant ES as Elasticsearch
    participant DB as MySQL
    participant B as 必应图片

    U->>F: 输入关键词 + 选择分类
    F->>C: POST /api/search/all

    alt 指定类型搜索 (type = post/user/picture)
        C->>SF: searchAll(request)
        SF->>R: getDataSourceByType(type)
        R-->>SF: 返回对应数据源
        SF->>ES: 查询文章 (BoolQuery)
        SF->>DB: 查询用户
        SF->>B: 爬取图片
    else 全类型搜索 (type 为空)
        C->>SF: searchAll(request)
        par CompletableFuture 并发
            SF->>ES: 文章查询任务
        and
            SF->>DB: 用户查询任务
        and
            SF->>B: 图片爬取任务
        end
        Note over SF: allOf().join() 等待全部完成
    end

    SF-->>C: SearchVO 聚合结果
    C-->>F: 统一响应
    F-->>U: 渲染对应列表
Loading

数据同步机制

flowchart LR
    subgraph 同步模式
        direction TB
        M1["📦 全量同步<br/>FullSyncPostToEs<br/>实现 CommandLineRunner<br/>项目启动时执行"]
        M2["🔄 增量同步<br/>IncSyncPostToEs<br/>@Scheduled 每60秒<br/>同步近5分钟变更"]
        M3["📡 Canal binlog<br/>监听 MySQL 变更<br/>实时同步(预留)"]
    end

    DB[(MySQL)] --> M1 --> ES[(Elasticsearch)]
    DB --> M2 --> ES
    DB -.->|binlog| M3 -.-> ES

    ES -->|"查询时回查 DB"| DB
    Note["ES 查询结果会回查 MySQL<br/>获取最新点赞数、收藏数"]
Loading

📡 API 接口

基础路径:/api · 接口文档:http://localhost:8102/api/doc.html

聚合搜索

方法 路径 说明 权限
POST /search/all 统一搜索入口,支持全类型/指定类型 公开

文章管理

方法 路径 说明 权限
POST /post/add 创建文章 登录
POST /post/edit 编辑文章 作者/管理员
POST /post/delete 删除文章 作者/管理员
GET /post/get/vo 获取文章详情 公开
POST /post/list/page/vo 分页查询(MySQL) 公开
POST /post/search/page/vo 分页搜索(Elasticsearch) 公开
POST /post/my/list/page/vo 我的文章 登录

用户管理

方法 路径 说明 权限
POST /user/register 用户注册 公开
POST /user/login 用户登录 公开
POST /user/logout 退出登录 公开
GET /user/get/login 获取当前登录用户 公开
GET /user/get/vo 根据ID获取用户信息 公开
POST /user/update/my 更新个人信息 登录
POST /user/add 创建用户 管理员
POST /user/delete 删除用户 管理员
POST /user/update 更新用户 管理员
POST /user/list/page 分页查询用户 管理员

互动功能

方法 路径 说明 权限
POST /post_thumb/ 点赞 / 取消点赞 登录
POST /post_favour/ 收藏 / 取消收藏 登录
POST /post_favour/my/list/page 我的收藏列表 登录

图片 & 文件

方法 路径 说明 权限
POST /picture/list/page/vo 搜索图片(必应爬虫) 公开
POST /file/upload 文件上传(腾讯云COS) 登录

🚀 快速开始

环境要求

环境 要求
JDK 1.8
Node.js 16+
MySQL 8.0+
Redis 6.0+
Elasticsearch 7.17.25(需与后端版本一致)

1. 准备数据库与中间件

# 创建数据库
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS allso DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# 导入建表语句
mysql -u root -p allso < sql/create_table.sql

启动 Redis 和 Elasticsearch 服务。

2. 配置后端

编辑 src/main/resources/application.yml,替换占位符:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/allso
    username: root
    password: <你的数据库密码>       # 替换 <Yours>
  redis:
    host: localhost
    port: 6379
  elasticsearch:
    uris: http://localhost:9200

cos:
  client:
    accessKey: <你的腾讯云AK>         # 替换 <Yours>
    secretKey: <你的腾讯云SK>         # 替换 <Yours>
    region: ap-guangzhou
    bucket: <你的存储桶名>

3. 启动后端

# 在项目根目录执行
mvnw spring-boot:run

启动后访问接口文档:http://localhost:8102/api/doc.html

4. 启动前端

cd allso-frontend
npm install        # 或 yarn install
npm run serve      # 或 yarn serve

访问 http://localhost:8080 即可使用。


🐳 Docker 部署

# 构建镜像
docker build -t allso-backend .

# 运行容器(需确保 MySQL/Redis/ES 可连通)
docker run -d --name allso -p 8102:8102 allso-backend

🎨 前端界面

前端采用紫蓝渐变背景 + 圆角卡片设计,包含三大搜索分类:

分类 组件 布局 数据来源
📝 文章 PostList 水平列表,头像+标题+内容 Elasticsearch
🖼️ 图片 PictureList 响应式网格(1/2/4/6列) 必应爬虫
👤 用户 UserList 响应式网格卡片 MySQL

路由采用 Hash 模式,支持通过 URL 参数共享搜索状态:/#/post?text=关键词


💡 设计亮点

数据源注册机制(开闭原则)

classDiagram
    class DataSource~T~ {
        <<interface>>
        +doSearch(searchText, pageNum, pageSize) Page~T~
    }

    class DataSourceRegistry {
        -Map dataSources
        +getDataSourceByType(type) DataSource
        +init()
    }

    class PostDataSource {
        +doSearch() 查询 Elasticsearch
    }

    class UserDataSource {
        +doSearch() 查询 MySQL
    }

    class PictureDataSource {
        +doSearch() 爬取必应图片
    }

    DataSource <|.. PostDataSource
    DataSource <|.. UserDataSource
    DataSource <|.. PictureDataSource
    DataSourceRegistry o--> DataSource
Loading

新增数据源只需实现 DataSource 接口并注册到 DataSourceRegistry,无需修改任何搜索逻辑。

应用的设计模式

模式 应用位置 作用
门面模式 SearchFacade 封装多数据源搜索复杂逻辑
策略模式 DataSource<T> 接口 可替换的搜索策略
注册表模式 DataSourceRegistry 动态分发数据源
AOP AuthInterceptor / LogInterceptor 权限校验、日志监控

❗ 所有权声明

本项目(Allso - 聚合搜索平台)由 chp 独立设计并开发,相关知识产权归作者所有。

  • 本项目仅用于 学术交流 目的,不得用于任何商业用途。
  • 未经作者书面许可,禁止将本项目代码、设计文档、论文内容等用于商业出版、售卖或二次分发。
  • 引用本项目代码或设计思想时,请注明出处并保留原作者信息。
  • 作者保留对本项目的最终解释权。

About

基于 Elasticsearch 一站式聚合搜索平台

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages