Files
work_dhd_back_end/doc/批量匹配方案设计.md
2026-01-06 11:23:52 +08:00

3.7 KiB
Raw Permalink Blame History

批量岗位匹配方案设计

需求分析

  • 场景1万个岗位与1个简历进行匹配
  • 要求:按匹配度排序,支持分页返回
  • 性能:需要考虑内存和计算效率

方案设计

方案一:全量计算+排序+分页(推荐)

优点

  • 实现简单
  • 排序准确(需要全部计算才能正确排序)
  • 支持分页

缺点

  • 需要计算所有岗位(即使只返回一页)
  • 内存占用较大1万个岗位约几MB

适用场景:岗位数量 < 5万单次请求可接受

实现思路

  1. 遍历所有岗位,计算匹配度
  2. 按匹配度降序排序
  3. 根据分页参数截取结果
  4. 返回分页数据

方案二:分批计算+分页(优化版)

优点

  • 内存占用可控
  • 可以提前终止如果只需要前N个

缺点

  • 实现复杂
  • 需要全部计算才能准确排序

适用场景:岗位数量 > 5万内存受限

实现思路

  1. 分批处理岗位如每批1000个
  2. 每批计算后合并排序
  3. 分页返回

方案三:快速过滤+精确计算(最佳性能)

优点

  • 性能最优
  • 可以快速过滤掉0分岗位

缺点

  • 需要两次遍历(先过滤,再计算)

适用场景大部分岗位匹配度为0的情况

实现思路

  1. 第一遍:快速检查硬性条件,过滤掉明显不匹配的
  2. 第二遍:对通过硬性条件的岗位进行详细计算
  3. 排序+分页

推荐实现:方案一(全量计算+排序+分页)

API设计

接口地址POST /match/batch

请求参数

{
  "positions": [
    { "id": 1, "position_require": {...} },
    { "id": 2, "position_require": {...} }
  ],
  "resume": { ... },
  "page": 1,           // 页码从1开始
  "page_size": 20,     // 每页数量默认20
  "filter_zero": false // 是否过滤0分岗位默认false
}

响应格式

{
  "code": 200,
  "data": {
    "list": [
      {
        "position_id": 2,
        "match_score": 95,
        "position": { ... }  // 可选,是否返回完整岗位信息
      }
    ],
    "pagination": {
      "page": 1,
      "page_size": 20,
      "total": 10000,
      "total_pages": 500,
      "has_more": true
    }
  }
}

性能估算

1万个岗位的计算时间

  • 单个岗位匹配计算:约 1-5ms
  • 1万个岗位约 10-50秒串行
  • 优化后(减少重复计算):约 5-25秒

内存占用

  • 单个岗位数据:约 1-5KB
  • 1万个岗位约 10-50MB
  • 匹配结果:约 5-10MB
  • 总计:约 15-60MB可接受

优化建议

  1. 可选过滤0分岗位

    • 如果 filter_zero=true,只返回匹配度>0的岗位
    • 可以减少返回数据量
  2. 可选:限制岗位数量

    • 如果岗位数量过大可以限制最大处理数量如最多1万个
  3. 可选:异步处理

    • 如果计算时间过长,可以考虑异步处理
    • 使用队列+轮询的方式
  4. 可选:缓存机制

    • 如果简历不变,可以缓存匹配结果
    • 使用 Redis 缓存key: resume_id, value: 匹配结果)

实现代码结构

// MatchService.php
public function batchMatch(
    array $positions, 
    array $resume, 
    int $page = 1, 
    int $pageSize = 20, 
    bool $filterZero = false
): array {
    // 1. 计算所有岗位的匹配度
    // 2. 排序
    // 3. 过滤(可选)
    // 4. 分页
    // 5. 返回结果
}

使用示例

// 控制器中调用
$matchService = new MatchService();
$result = $matchService->batchMatch(
    $positions,      // 1万个岗位
    $resume,         // 简历
    1,               // 第1页
    20,              // 每页20条
    false            // 不过滤0分
);