编辑 | blame | 历史 | 原始文档

医院分词搜索功能 - 快速使用指南

一、部署步骤(4步完成)

步骤1: 集成 HanLP 分词库

说明: 已集成 HanLP 专业中文分词库,替代了简单的 N-Gram 算法,分词准确度更高。

ruoyi-common/pom.xml 中已添加:
xml <!-- HanLP 中文分词库 --> <dependency> <groupId>com.hankcs</groupId> <artifactId>hanlp</artifactId> <version>portable-1.8.4</version> </dependency>

步骤2: 执行数据库脚本

# 进入 SQL 目录
cd sql

# 1. 执行脚本添加分词字段
mysql -uroot -p你的密码 你的数据库名 < tb_hosp_data_add_keywords.sql

# 2. 添加后台菜单权限
mysql -uroot -p你的密码 你的数据库名 < hospital_tokenizer_menu.sql

步骤3: 重启应用

# Linux/Mac
./ry.sh restart

# Windows
ry.bat

步骤4: 使用后台测试界面初始化分词

方式1: 通过后台界面(推荐)

  1. 登录后台管理系统
  2. 进入菜单:**系统管理 > 医院管理 > 医院分词测试**
  3. 点击「**批量生成所有医院分词**」按钮
  4. 等待生成完成

方式2: 通过 API 接口

使用 Postman 或浏览器访问:
GET http://localhost:8080/system/hospital/generateKeywords

等待返回结果,显示成功生成的医院数量。


二、后台测试界面使用

访问路径

系统管理 > 医院管理 > 医院分词测试

功能说明

1. 批量分词管理

  • 功能: 为所有医院批量生成分词数据
  • 使用场景:
  • 首次部署时初始化
  • 分词算法升级后重新生成
  • 数据修复后更新
  • 操作: 点击「批量生成所有医院分词」按钮
  • 耗时: 根据医院数量,通常需要 1-5 分钟

2. 医院匹配测试

  • 功能: 测试分词搜索效果
  • 使用方法:
  1. 在搜索框输入医院名称、地址或关键词
  2. 设置返回结果数量(默认 30 条)
  3. 点击「搜索」按钮
  4. 查看匹配结果(按相关度排序)

3. 测试示例

输入: "北京协和医院"
结果: 显示所有包含“北京”和“协和”的医院

输入: "上海瑞金医院卢湾区"
结果: 上海瑞金医院及其分院排在最前

输入: "人民医院朝阳区"
结果: 朝阳区的人民医院相关结果

界面截图说明

  1. 批量分词区域
  • 展示提示信息
  • 生成按钮(带 loading 状态)
  • 结果显示(成功/失败)
  1. 搜索测试区域
  • 搜索输入框
  • 结果数量设置
  • 分词结果展示(标签形式)
  • 医院列表表格
  • 统计信息

三、API 接口使用

接口1: 批量生成分词(管理员)

接口: GET /system/hospital/generateKeywords

说明: 批量为所有医院生成分词,用于初始化或重新生成

请求示例:
bash curl -X GET "http://localhost:8080/system/hospital/generateKeywords"

返回示例:
json { "code": 200, "msg": "成功生成 1523 个医院的分词" }


接口2: 分词搜索医院(核心功能)

接口: GET /system/hospital/searchByKeywords

参数:
| 参数 | 类型 | 必填 | 说明 | 示例 |
|-----|------|------|------|------|
| searchText | String | 是 | 搜索文本 | "北京协和东城区" |
| pageSize | Integer | 否 | 返回数量,默认50 | 20 |

请求示例:
```bash

搜索 "北京协和医院"

curl -X GET "http://localhost:8080/system/hospital/searchByKeywords?searchText=北京协和医院&pageSize=20"

搜索 "上海瑞金"

curl -X GET "http://localhost:8080/system/hospital/searchByKeywords?searchText=上海瑞金"
```

返回示例:
json { "code": 200, "msg": "查询成功", "data": [ { "hospId": 1001, "hospName": "北京协和医院", "hospShort": "协和医院", "hopsProvince": "北京市", "hopsCity": "北京市", "hopsArea": "东城区", "hospAddress": "东城区帅府园1号", "hospTel": "010-69156114" }, { "hospId": 1002, "hospName": "首都医科大学附属北京协和医院西院", "hospShort": "协和西院", "hopsProvince": "北京市", "hopsCity": "北京市", "hopsArea": "西城区", "hospAddress": "西城区大木仓胡同41号" } // ... 更多匹配结果(按匹配度自动排序) ] }


四、前端集成示例

uni-app 集成

// 在你的页面或组件中
export default {
  data() {
    return {
      searchText: '',
      hospitals: []
    }
  },
  methods: {
    // 搜索医院
    searchHospitals() {
      if (!this.searchText.trim()) {
        uni.showToast({
          title: '请输入搜索内容',
          icon: 'none'
        });
        return;
      }
      
      uni.showLoading({ title: '搜索中...' });
      
      uni.request({
        url: this.$baseUrl + '/system/hospital/searchByKeywords',
        method: 'GET',
        data: {
          searchText: this.searchText,
          pageSize: 30
        },
        success: (res) => {
          uni.hideLoading();
          
          if (res.data.code === 200) {
            this.hospitals = res.data.data;
            console.log('找到医院:', this.hospitals.length);
            
            if (this.hospitals.length === 0) {
              uni.showToast({
                title: '未找到匹配的医院',
                icon: 'none'
              });
            }
          } else {
            uni.showToast({
              title: res.data.msg || '搜索失败',
              icon: 'none'
            });
          }
        },
        fail: (err) => {
          uni.hideLoading();
          uni.showToast({
            title: '网络请求失败',
            icon: 'none'
          });
          console.error('搜索失败:', err);
        }
      });
    },
    
    // 选择医院
    selectHospital(hospital) {
      // 将选中的医院信息回填到表单
      console.log('选择了医院:', hospital.hospName);
      // 你的业务逻辑...
    }
  }
}

Vue.js + Axios 集成

// 在 Vue 组件中
<template>
  <div>
    <el-input 
      v-model="searchText" 
      placeholder="输入医院名称或地址"
      @keyup.enter="searchHospitals">
      <el-button slot="append" icon="el-icon-search" @click="searchHospitals"></el-button>
    </el-input>
    
    <el-table :data="hospitals" v-loading="loading">
      <el-table-column prop="hospName" label="医院名称"></el-table-column>
      <el-table-column prop="hopsCity" label="城市"></el-table-column>
      <el-table-column prop="hospAddress" label="地址"></el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button size="mini" @click="selectHospital(scope.row)">选择</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      searchText: '',
      hospitals: [],
      loading: false
    }
  },
  methods: {
    async searchHospitals() {
      if (!this.searchText.trim()) {
        this.$message.warning('请输入搜索内容');
        return;
      }
      
      this.loading = true;
      
      try {
        const response = await this.$http.get('/system/hospital/searchByKeywords', {
          params: {
            searchText: this.searchText,
            pageSize: 50
          }
        });
        
        if (response.data.code === 200) {
          this.hospitals = response.data.data;
          
          if (this.hospitals.length === 0) {
            this.$message.info('未找到匹配的医院');
          } else {
            this.$message.success(`找到 ${this.hospitals.length} 个匹配的医院`);
          }
        } else {
          this.$message.error(response.data.msg || '搜索失败');
        }
      } catch (error) {
        console.error('搜索失败:', error);
        this.$message.error('网络请求失败');
      } finally {
        this.loading = false;
      }
    },
    
    selectHospital(hospital) {
      // 处理选择医院的逻辑
      console.log('选择了医院:', hospital);
      this.$emit('hospital-selected', hospital);
    }
  }
}
</script>

五、功能说明

1. 分词特点

  • HanLP 专业分词: 使用业界通用的 HanLP 中文分词库
  • 智能分词: 自动将医院名称、地址等分解为多个关键词
  • 停用词过滤: 过滤“医院”、“市”、“省”等常见词
  • 降级方案: HanLP 失败时自动降级到 N-Gram 算法
  • 支持模糊匹配: 输入部分关键词即可匹配

2. 权重排序

  • 匹配的关键词越多,排名越靠前
  • 完全匹配优先于部分匹配
  • 自动按相关度排序,无需手动筛选

3. 使用场景

  • ✅ 用户输入 "北京协和" → 匹配所有带"北京"和"协和"的医院
  • ✅ 用户输入 "东城区人民" → 匹配"东城区"和"人民"相关的医院
  • ✅ 用户输入 "瑞金医院卢湾" → 匹配上海瑞金医院及其分院

六、常见问题

Q1: 首次部署后搜索不到任何结果?

A: 需要先调用 /generateKeywords 接口初始化分词数据。

Q2: 新增或修改医院后需要重新生成分词吗?

A: 不需要。系统会自动在新增/修改/同步医院时生成分词。

Q3: 搜索速度慢怎么办?

A:
1. 确认已经在 hosp_keywords 字段上创建索引
2. 适当减小 pageSize 参数值
3. 考虑增加服务器内存

Q4: 后台菜单看不到“医院管理”?

A:
1. 确认执行了 hospital_tokenizer_menu.sql 脚本
2. 在“系统管理 > 角色管理”中,给当前角色分配菜单权限
3. 重新登录后台系统

Q5: HanLP 分词库下载慢怎么办?

A:
1. 使用阿里云或腾讯云 Maven 镜像
2. 或者手动下载 HanLP jar 包放到本地 Maven 仓库

Q6: 如何优化搜索准确度?

A:
1. 调整 HospitalTokenizerUtil 中的停用词列表
2. 根据业务需求添加医院别名映射
3. 使用后台测试界面反复测试和调优


七、维护建议

定期维护

# 建议每月重新生成一次分词(可选)
GET /system/hospital/generateKeywords

监控日志

查看应用日志中的分词生成信息:
bash tail -f logs/sys-info.log | grep "医院分词"

数据备份

# 定期备份医院数据
mysqldump -u用户名 -p数据库名 tb_hosp_data > hosp_data_backup.sql

七、技术支持

如遇到问题,请检查:
1. 数据库字段是否正确添加
2. 应用是否正常重启
3. 分词数据是否已初始化
4. 接口权限是否配置正确

详细技术文档请参考: 医院信息分词搜索功能说明.md


版本: v1.0
更新日期: 2026-01-20