# 医院信息分词搜索功能说明 ## 功能概述 本功能实现了基于中文分词的医院信息智能搜索,通过对医院名称、地址等信息进行分词处理,支持模糊匹配和权重排序,大幅提升医院搜索的准确性和用户体验。 ## 实现内容 ### 1. 数据库层面 #### 1.1 新增分词字段 - **文件**: `sql/tb_hosp_data_add_keywords.sql` - **内容**: 在 `tb_hosp_data` 表中添加 `hosp_keywords` 字段 ```sql ALTER TABLE `tb_hosp_data` ADD COLUMN `hosp_keywords` varchar(500) DEFAULT NULL COMMENT '医院信息分词(逗号分隔)'; CREATE INDEX idx_hosp_keywords ON tb_hosp_data(hosp_keywords); ``` ### 2. 实体类层面 #### 2.1 TbHospData 实体扩展 - **文件**: `ruoyi-system/src/main/java/com/ruoyi/system/domain/TbHospData.java` - **新增字段**: - `hospKeywords` - 医院信息分词(逗号分隔) - **包含方法**: getter、setter 及 toString ### 3. 分词工具类 #### 3.1 HospitalTokenizerUtil - **文件**: `ruoyi-common/src/main/java/com/ruoyi/common/utils/HospitalTokenizerUtil.java` - **核心功能**: 1. **中文分词**: 使用 N-Gram 算法对医院信息进行分词(2-4字符组合) 2. **停用词过滤**: 自动过滤"医院"、"市"、"省"等常见停用词 3. **关键词提取**: 从医院名称、简称、省市区、地址中提取关键词 4. **匹配度计算**: 计算两个分词集合的匹配分数 - **主要方法**: ```java // 生成医院信息的分词 public static String tokenize(String hospName, String hospShort, String province, String city, String area, String address) // 对搜索文本进行分词 public static String tokenizeSearchText(String text) // 计算两个分词集合的匹配度 public static int calculateMatchScore(String keywords1, String keywords2) ``` ### 4. Service 层 #### 4.1 ITbHospDataService 接口扩展 - **文件**: `ruoyi-system/src/main/java/com/ruoyi/system/service/ITbHospDataService.java` - **新增方法**: ```java // 批量生成并更新所有医院的分词 int generateAllHospitalKeywords(); // 为单个医院生成分词 String generateKeywordsForHospital(TbHospData tbHospData); ``` #### 4.2 TbHospDataServiceImpl 实现 - **文件**: `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TbHospDataServiceImpl.java` - **功能**: - 批量处理所有医院数据,生成分词并更新数据库 - 单个医院分词生成,在新增/更新医院时自动调用 #### 4.3 HospDataSyncServiceImpl 集成 - **文件**: `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/HospDataSyncServiceImpl.java` - **功能**: 在医院同步时自动生成分词 - 从 SQL Server 同步医院数据时,自动调用分词生成 - 确保所有医院数据都有最新的分词信息 ### 5. Controller 层 #### 5.1 HospDataController 扩展 - **文件**: `ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/HospDataController.java` ##### 5.1.1 批量生成分词接口 - **接口**: `GET /system/hospital/generateKeywords` - **功能**: 批量生成所有医院的分词(管理员接口) - **返回**: 更新的医院数量 - **使用场景**: - 首次部署时初始化所有医院分词 - 分词算法升级后重新生成分词 ##### 5.1.2 基于分词匹配搜索接口 - **接口**: `GET /system/hospital/searchByKeywords` - **参数**: - `searchText` (必填): 搜索文本(医院名称、地址等) - `pageSize` (可选): 返回结果数量,默认 50 - **功能流程**: 1. 对前端传入的搜索文本进行分词 2. 查询所有正常状态的医院数据 3. 计算每个医院与搜索文本的匹配分数 4. 按匹配分数降序排序(权重排序) 5. 返回匹配的医院列表 - **返回示例**: ```json { "code": 200, "msg": "查询成功", "data": [ { "hospId": 1001, "hospName": "北京协和医院", "hospShort": "协和医院", "hopsProvince": "北京市", "hopsCity": "北京市", "hopsArea": "东城区", "hospAddress": "东城区帅府园1号" }, // ... 更多医院数据(按匹配度排序) ] } ``` ### 6. Mapper XML 更新 #### 6.1 TbHospDataMapper.xml - **文件**: `ruoyi-system/src/main/resources/mapper/system/TbHospDataMapper.xml` - **更新内容**: - ResultMap 添加 `hospKeywords` 字段映射 - SELECT 语句包含 `hosp_keywords` 字段 - INSERT 和 UPDATE 支持 `hosp_keywords` 字段 ## 使用说明 ### 部署步骤 1. **执行数据库脚本** ```bash mysql -u用户名 -p数据库名 < sql/tb_hosp_data_add_keywords.sql ``` 2. **重启应用** ```bash ./ry.sh restart # 或 Windows 下 ry.bat ``` 3. **初始化分词数据** 调用批量生成分词接口: ```bash GET http://localhost:8080/system/hospital/generateKeywords ``` ### 前端集成示例 #### 使用分词搜索接口 ```javascript // 在 uni-app 中调用 uni.request({ url: '/system/hospital/searchByKeywords', method: 'GET', data: { searchText: '北京协和东城区', pageSize: 20 }, success: (res) => { if (res.data.code === 200) { // 医院列表已按匹配度排序 const hospitals = res.data.data; console.log('找到医院:', hospitals.length); } } }); ``` #### Vue.js 示例 ```javascript // 在 Vue 组件中 methods: { async searchHospitals(searchText) { try { const response = await this.$http.get('/system/hospital/searchByKeywords', { params: { searchText: searchText, pageSize: 50 } }); if (response.data.code === 200) { this.hospitals = response.data.data; // 数据已按匹配度排序,匹配越好的医院越靠前 } } catch (error) { console.error('搜索失败:', error); } } } ``` ## 功能特点 ### 1. 智能分词 - 使用 N-Gram 算法生成 2-4 字符的关键词组合 - 自动提取单个中文字符作为补充关键词 - 支持对医院名称、简称、省市区、地址等多个字段分词 ### 2. 停用词过滤 自动过滤以下常见停用词: - 通用词: "医院"、"诊所"、"卫生"、"院" - 地区词: "市"、"省"、"县"、"区"、"镇"、"乡" - 位置词: "街道"、"路"、"号"、"栋"、"单元"、"室"、"层"、"楼" - 连接词: "的"、"了"、"在"、"与"、"和"、"及"等 ### 3. 权重排序 - 根据匹配的关键词数量计算匹配分数 - 匹配的分词越多,排名越靠前 - 精确匹配优先于模糊匹配 ### 4. 自动化集成 - 医院同步时自动生成分词 - 新增或更新医院时自动更新分词 - 无需手动干预,确保数据一致性 ## 性能优化 1. **索引优化**: 在 `hosp_keywords` 字段上创建索引,提升查询性能 2. **内存计算**: 匹配度计算在内存中进行,避免数据库压力 3. **结果限制**: 支持 `pageSize` 参数限制返回数量,减少网络传输 ## 注意事项 1. **首次部署**: 必须调用 `/generateKeywords` 接口初始化所有医院的分词数据 2. **数据同步**: 医院同步会自动更新分词,无需额外操作 3. **分词质量**: 分词算法基于简单的 N-Gram,对于复杂的医院名称可能需要优化 4. **停用词维护**: 可根据实际业务需求在 `HospitalTokenizerUtil` 中调整停用词列表 ## 后续优化建议 1. **集成第三方分词**: - 可考虑集成 IK Analyzer、HanLP 等专业中文分词库 - 提升分词准确度和召回率 2. **拼音支持**: - 增加拼音索引,支持拼音首字母搜索 - 例如: "bjxhyy" 可以匹配"北京协和医院" 3. **同义词扩展**: - 支持同义词匹配 - 例如: "人民医院" 和 "人民医疗中心" 4. **搜索历史**: - 记录用户搜索历史 - 根据历史数据优化排序算法 5. **地理位置权重**: - 结合用户位置信息 - 优先返回附近的医院 ## 技术栈 - **后端框架**: Spring Boot + MyBatis - **数据库**: MySQL 5.7+ - **工具类**: Apache Commons Lang3 - **日志**: SLF4J + Logback ## 联系方式 如有问题或建议,请联系开发团队。 --- **文档版本**: v1.0 **更新日期**: 2026-01-20 **开发者**: RuoYi Team