# 搜索引擎 **本文引用的文件** - [internal/search/meilisearch.go](file://internal/search/meilisearch.go) - [internal/config/meilisearch.go](file://internal/config/meilisearch.go) - [internal/config/config.go](file://internal/config/config.go) - [cmd/server/main.go](file://cmd/server/main.go) - [internal/router/router.go](file://internal/router/router.go) - [internal/handler/model_list.go](file://internal/handler/model_list.go) - [internal/handler/model.go](file://internal/handler/model.go) - [internal/repository/model.go](file://internal/repository/model.go) - [internal/model/model.go](file://internal/model/model.go) - [internal/database/mysql.go](file://internal/database/mysql.go) - [internal/cache/redis.go](file://internal/cache/redis.go) - [internal/response/response.go](file://internal/response/response.go) - [README.md](file://README.md) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向 Luxsin 应用 API 项目中的搜索引擎集成,系统性介绍 Meilisearch 的配置与初始化、搜索客户端的创建流程、索引管理策略、全文搜索实现原理以及搜索 API 的使用示例。同时提供性能优化建议、高亮显示、自动补全与相关性排序的扩展思路,以及连接问题诊断、索引重建与性能调优的故障排除指南。内容从基础概念到高级应用,兼顾不同层次开发者需求。 ## 项目结构 该项目采用分层架构,围绕 Gin HTTP 框架组织模块: - 配置层:集中加载运行环境、数据库、Meilisearch、Redis 等配置 - 数据访问层:MySQL 数据库连接与模型扫描 - 搜索层:Meilisearch 客户端与搜索请求封装 - 处理层:HTTP 处理器与路由注册 - 缓存层:Redis 客户端(用于查询缓存等) - 工具层:统一响应体、日志、编码工具 ```mermaid graph TB subgraph "应用入口" MAIN["cmd/server/main.go"] end subgraph "配置层" CFG["internal/config/config.go"] MS_CFG["internal/config/meilisearch.go"] end subgraph "数据访问层" MYSQL["internal/database/mysql.go"] REPO["internal/repository/model.go"] MODEL["internal/model/model.go"] end subgraph "搜索层" SEARCH_CLIENT["internal/search/meilisearch.go"] end subgraph "处理层" ROUTER["internal/router/router.go"] HANDLER_MODEL["internal/handler/model.go"] HANDLER_MODEL_LIST["internal/handler/model_list.go"] end subgraph "缓存层" REDIS["internal/cache/redis.go"] end MAIN --> CFG CFG --> MS_CFG MAIN --> MYSQL MAIN --> SEARCH_CLIENT MAIN --> REDIS ROUTER --> HANDLER_MODEL ROUTER --> HANDLER_MODEL_LIST HANDLER_MODEL --> REPO SEARCH_CLIENT --> MS_CFG ``` 图表来源 - [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) - [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51) - [internal/config/meilisearch.go:14-37](file://internal/config/meilisearch.go#L14-L37) - [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46) - [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20) - [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) - [internal/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24) - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) 章节来源 - [README.md:5-17](file://README.md#L5-L17) - [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) - [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51) ## 核心组件 - 配置加载与验证:集中加载运行环境、数据库、Meilisearch、Redis 配置,并进行必填项校验 - Meilisearch 客户端:封装搜索请求,限定返回字段,支持上下文取消 - 路由与处理器:对外提供 /audio/modelList 搜索接口,支持分页数量控制与可选 Base64 响应 - 数据访问层:提供按品牌名或型号名的 SQL 查询能力(当前未直接使用 Meilisearch) - 缓存层:Redis 客户端,可用于查询结果缓存 章节来源 - [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12) - [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50) - [internal/search/meilisearch.go:13-15](file://internal/search/meilisearch.go#L13-L15) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) - [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56) - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) ## 架构总览 应用启动时加载配置,建立数据库与 Meilisearch 连接,注册路由并启动 HTTP 服务。搜索请求通过 /audio/modelList 路由进入处理器,处理器调用搜索客户端执行全文检索,最终以 JSON 或 Base64 编码形式返回。 ```mermaid sequenceDiagram participant Client as "客户端" participant Router as "路由" participant Handler as "ModelListHandler" participant Search as "Meilisearch Client" participant Engine as "HTTP 引擎" Client->>Engine : "GET /audio/modelList?key=...&count=..." Engine->>Router : "匹配 /audio/modelList" Router->>Handler : "调用 ModelList()" Handler->>Handler : "解析查询参数
解析 count 与 Base64 选项" Handler->>Search : "ModelList(ctx, key, count)" Search->>Search : "构造 SearchRequest
限制返回字段" Search-->>Handler : "返回 hits 列表" Handler-->>Client : "JSON 或 Base64 响应" ``` 图表来源 - [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) - [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) ## 详细组件分析 ### 配置加载与验证 - 配置结构包含运行环境、监听地址、端口、数据库、Meilisearch、Redis 等字段 - 加载逻辑按环境选择默认值,支持通过环境变量覆盖 - Meilisearch 配置包含 Host、APIKey、Index,均需校验非空 - 启动日志记录已配置的 Meilisearch 主机与索引 章节来源 - [internal/config/config.go:9-16](file://internal/config/config.go#L9-L16) - [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51) - [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12) - [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50) - [cmd/server/main.go:50-54](file://cmd/server/main.go#L50-L54) ### Meilisearch 客户端 - 客户端封装了 IndexManager,负责全文搜索 - 初始化时传入 Host 与 APIKey,选择指定 Index - ModelList 方法接收 key 与 count,限制返回字段,解码为 map 并返回 - 错误处理统一包装,便于上层捕获 ```mermaid classDiagram class Client { -index : "IndexManager" +NewClient(cfg) : "Client" +ModelList(ctx, key, count) : "[]map[string]any, error" } class MeilisearchConfig { +Host : "string" +APIKey : "string" +Index : "string" +validate() : "error" } Client --> MeilisearchConfig : "依赖" ``` 图表来源 - [internal/search/meilisearch.go:13-20](file://internal/search/meilisearch.go#L13-L20) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) - [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12) - [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50) 章节来源 - [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) ### 路由与处理器 - 路由在 /audio 下注册 /modelList 接口 - ModelListHandler 解析查询参数 key、count,并支持 Base64 响应 - 调用搜索客户端执行搜索,错误时返回统一错误响应 ```mermaid sequenceDiagram participant C as "客户端" participant R as "路由" participant H as "ModelListHandler" participant S as "Meilisearch Client" C->>R : "GET /audio/modelList?key=...&count=..." R->>H : "ModelList()" H->>H : "解析 key/count/base64" H->>S : "ModelList(ctx, key, count)" S-->>H : "hits" H-->>C : "JSON 或 Base64" ``` 图表来源 - [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) - [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45) 章节来源 - [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38) - [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56) ### 数据访问层(SQL 查询) - ModelRepository 支持按品牌名精确匹配与按型号名模糊匹配 - 默认不使用 Meilisearch,直接走数据库查询 - 可作为搜索降级路径或补充场景 ```mermaid flowchart TD Start(["进入 List"]) --> Trim["去除前后空格"] Trim --> Switch{"条件分支"} Switch --> |brandName 非空| BrandQuery["按品牌名精确查询
按名称升序"] Switch --> |modelName 非空| LikeQuery["按型号名模糊查询
按名称升序"] Switch --> |否则| Empty["返回空数组"] BrandQuery --> Exec["执行查询"] LikeQuery --> Exec Exec --> Scan["逐行扫描并组装模型"] Scan --> End(["返回结果"]) Empty --> End ``` 图表来源 - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) 章节来源 - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) ### 数据库连接与模型扫描 - 使用 go-sql-driver/mysql 建立连接,设置字符集、时区与连接池参数 - PingContext 超时检测连接可用性 - 扫描函数将 NullString 转换为指针类型,避免空值污染 章节来源 - [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46) - [internal/repository/model.go:63-86](file://internal/repository/model.go#L63-L86) ### 缓存层(Redis) - 提供 NewClient 工厂方法,按配置创建 Redis 客户端 - 可用于搜索结果缓存、热门关键词缓存等 章节来源 - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) ## 依赖关系分析 - 入口 main 依赖配置加载、数据库、Meilisearch、Redis 与路由 - 路由依赖处理器,处理器依赖搜索客户端与数据库 - 搜索客户端依赖配置模块与 Meilisearch SDK - 数据库层依赖 MySQL 驱动与配置 ```mermaid graph LR MAIN["cmd/server/main.go"] --> CFG["internal/config/config.go"] MAIN --> MYSQL["internal/database/mysql.go"] MAIN --> SEARCH["internal/search/meilisearch.go"] MAIN --> REDIS["internal/cache/redis.go"] ROUTER["internal/router/router.go"] --> HANDLER1["internal/handler/model.go"] ROUTER --> HANDLER2["internal/handler/model_list.go"] HANDLER2 --> SEARCH HANDLER1 --> REPO["internal/repository/model.go"] REPO --> MODEL["internal/model/model.go"] ``` 图表来源 - [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64) - [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51) - [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46) - [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20) - [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16) - [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41) - [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24) - [internal/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24) - [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61) - [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14) ## 性能考虑 - 索引预处理 - 在导入数据前,确保字段映射与排序规则已配置,减少运行时开销 - 对高频查询字段(如品牌名、型号名)建立合适字段权重 - 查询缓存 - 使用 Redis 缓存热点搜索结果,设置合理过期时间 - 对于稳定不变的数据(如品牌列表),可缓存静态结果 - 分页策略 - 控制 count 参数上限,避免一次性返回过多数据 - 结合游标分页或基于主键的分页,提升大结果集性能 - 连接池与超时 - 数据库连接池参数已设置,搜索客户端使用短连接或复用连接视场景而定 - 设置合理的读写超时与上下文取消,防止阻塞 - 字段裁剪 - 仅返回必要字段,降低网络传输与序列化成本 - 相关性与排序 - 使用 Meilisearch 的排序与过滤能力,避免后端二次排序 - 日志与监控 - 记录搜索耗时、命中率与错误统计,便于定位性能瓶颈 ## 故障排除指南 - 连接问题诊断 - 检查 MEILISEARCH_HOST、MEILISEARCH_API_KEY、MEILISEARCH_INDEX 是否正确设置 - 确认 Meilisearch 服务可达且端口开放 - 查看启动日志中 Meilisearch 配置是否正确加载 - 索引重建 - 如需重建索引,先清空旧索引,再批量导入数据,最后更新字段映射与排序规则 - 导入完成后进行回归测试,确保搜索结果符合预期 - 性能调优 - 逐步增加 count 上限,观察延迟变化,找到平衡点 - 对热点查询启用缓存,减少重复请求 - 优化数据库查询(如品牌/型号过滤)作为降级方案 - 错误处理 - 搜索失败时返回统一错误响应,便于前端提示 - 对 decode 失败、上下文取消等异常进行分类处理 章节来源 - [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50) - [cmd/server/main.go:50-54](file://cmd/server/main.go#L50-L54) - [internal/handler/model_list.go:37-42](file://internal/handler/model_list.go#L37-L42) - [internal/response/response.go:34-36](file://internal/response/response.go#L34-L36) ## 结论 本项目已实现 Meilisearch 的基础集成:配置加载、客户端初始化与搜索接口。当前搜索接口主要返回指定字段的命中结果,未涉及高亮、自动补全与相关性排序的高级特性。建议后续在以下方面增强: - 高亮显示:利用 Meilisearch 的高亮能力,返回匹配片段 - 自动补全:结合前缀匹配与热门词,提供输入建议 - 相关性排序:配置字段权重与排序规则,提升搜索体验 - 索引策略:按业务维度拆分索引,优化写入与查询性能 - 缓存策略:引入 Redis 缓存,显著降低重复查询延迟 ## 附录 ### 搜索 API 使用示例 - 设备型号搜索 - 请求:GET /audio/modelList?key=型号关键词&count=100 - 响应:返回命中的设备列表(仅包含指定字段) - 品牌过滤 - 当前未直接使用 Meilisearch 实现品牌过滤,可通过数据库查询替代 - 请求:GET /audio/getModel?brandName=品牌名 - 结果排序 - 当前未显式设置排序,可结合 Meilisearch 的排序规则实现 - Base64 响应 - 可通过查询参数 base64=true 获取 Base64 编码的 JSON 章节来源 - [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56) - [internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50) - [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)