# 批量岗位匹配方案设计 ## 需求分析 - **场景**:1万个岗位与1个简历进行匹配 - **要求**:按匹配度排序,支持分页返回 - **性能**:需要考虑内存和计算效率 ## 方案设计 ### 方案一:全量计算+排序+分页(推荐) **优点**: - 实现简单 - 排序准确(需要全部计算才能正确排序) - 支持分页 **缺点**: - 需要计算所有岗位(即使只返回一页) - 内存占用较大(1万个岗位约几MB) **适用场景**:岗位数量 < 5万,单次请求可接受 **实现思路**: 1. 遍历所有岗位,计算匹配度 2. 按匹配度降序排序 3. 根据分页参数截取结果 4. 返回分页数据 ### 方案二:分批计算+分页(优化版) **优点**: - 内存占用可控 - 可以提前终止(如果只需要前N个) **缺点**: - 实现复杂 - 需要全部计算才能准确排序 **适用场景**:岗位数量 > 5万,内存受限 **实现思路**: 1. 分批处理岗位(如每批1000个) 2. 每批计算后合并排序 3. 分页返回 ### 方案三:快速过滤+精确计算(最佳性能) **优点**: - 性能最优 - 可以快速过滤掉0分岗位 **缺点**: - 需要两次遍历(先过滤,再计算) **适用场景**:大部分岗位匹配度为0的情况 **实现思路**: 1. 第一遍:快速检查硬性条件,过滤掉明显不匹配的 2. 第二遍:对通过硬性条件的岗位进行详细计算 3. 排序+分页 ## 推荐实现:方案一(全量计算+排序+分页) ### API设计 **接口地址**:`POST /match/batch` **请求参数**: ```json { "positions": [ { "id": 1, "position_require": {...} }, { "id": 2, "position_require": {...} } ], "resume": { ... }, "page": 1, // 页码,从1开始 "page_size": 20, // 每页数量,默认20 "filter_zero": false // 是否过滤0分岗位,默认false } ``` **响应格式**: ```json { "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: 匹配结果) ## 实现代码结构 ```php // MatchService.php public function batchMatch( array $positions, array $resume, int $page = 1, int $pageSize = 20, bool $filterZero = false ): array { // 1. 计算所有岗位的匹配度 // 2. 排序 // 3. 过滤(可选) // 4. 分页 // 5. 返回结果 } ``` ## 使用示例 ```php // 控制器中调用 $matchService = new MatchService(); $result = $matchService->batchMatch( $positions, // 1万个岗位 $resume, // 简历 1, // 第1页 20, // 每页20条 false // 不过滤0分 ); ```