Explorar el Código

匹配功能优化

yuxy hace 6 horas
padre
commit
1633d92314

+ 50 - 7
service/randomMatch/src/main/java/com/zhentao/service/MatchService.java

@@ -169,6 +169,18 @@ public class MatchService {
             Set<String> matchedHistory = getMatchedHistory(userId);
             Set<String> unmatched = redisMatchPool.getUserUnmatchedSet(userId);
             
+            // 检查是否所有用户都已匹配过,如果是则清空历史实现循环匹配
+            int totalAvailableUsers = (int) allUsers.stream()
+                .filter(u -> !userId.equals(String.valueOf(u.getUserId())))
+                .count();
+            
+            if (matchedHistory.size() >= totalAvailableUsers && totalAvailableUsers > 0) {
+                log.info("所有用户已匹配完,清空历史实现循环匹配: userId={}, 历史数={}, 总用户数={}", 
+                    userId, matchedHistory.size(), totalAvailableUsers);
+                clearMatchedHistory(userId);
+                matchedHistory = new HashSet<>();
+            }
+            
             // 打乱用户列表,增加随机性
             Collections.shuffle(allUsers);
             
@@ -194,13 +206,20 @@ public class MatchService {
                 MatchData otherData = buildMatchDataFromUser(user);
                 if (otherData == null) continue;
                 
-                // 根据匹配模式进行额外筛选
-                if (!shouldMatchByMode(userData, otherData, matchMode)) {
+                // 计算匹配分数
+                double score = MatchingAlgorithmUtils.calculateMatchScore(userData, otherData);
+                
+                // 根据匹配模式进行额外筛选(但不阻断匹配)
+                boolean matchesModeRequirements = shouldMatchByMode(userData, otherData, matchMode);
+                // 精准模式下,如果不符合条件,降低分数但不完全排除
+                if (!matchesModeRequirements && "precise".equalsIgnoreCase(matchMode)) {
+                    // 精准模式下不符合条件的用户,分数打折
+                    score = score * 0.7;
+                } else if (!matchesModeRequirements) {
+                    // 其他模式下不符合条件直接跳过
                     continue;
                 }
                 
-                // 计算匹配分数
-                double score = MatchingAlgorithmUtils.calculateMatchScore(userData, otherData);
                 scores.put(otherUserId, score);
                 
                 // 收集达到阈值的匹配
@@ -234,9 +253,11 @@ public class MatchService {
                 // 取前5个最高分的
                 List<Map.Entry<String, Double>> topScores = sortedScores.subList(0, Math.min(5, sortedScores.size()));
                 
-                // 降低阈值要求,只要分数大于30就可以匹配
+                // 精准模式下降低阈值到20,其他模式30
+                double minScore = "precise".equalsIgnoreCase(matchMode) ? 20.0 : 30.0;
+                
                 List<Map.Entry<String, Double>> acceptableMatches = topScores.stream()
-                    .filter(e -> e.getValue() >= 30.0)
+                    .filter(e -> e.getValue() >= minScore)
                     .collect(java.util.stream.Collectors.toList());
                 
                 if (!acceptableMatches.isEmpty()) {
@@ -246,7 +267,16 @@ public class MatchService {
                     // 记录匹配历史
                     addToMatchedHistory(userId, selected.getKey());
                     
-                    log.info("从数据库匹配成功(降低阈值): userId={}, matchedUserId={}, score={}", 
+                    log.info("从数据库匹配成功(降低阈值): userId={}, matchedUserId={}, score={}, mode={}", 
+                        userId, selected.getKey(), selected.getValue(), matchMode);
+                    return new MatchResult(true, selected.getKey(), selected.getValue());
+                }
+                
+                // 如果连最低分数都不满足,但有候选人,就选择分数最高的
+                if (!topScores.isEmpty()) {
+                    Map.Entry<String, Double> selected = topScores.get(0);
+                    addToMatchedHistory(userId, selected.getKey());
+                    log.info("从数据库匹配成功(最低阈值): userId={}, matchedUserId={}, score={}", 
                         userId, selected.getKey(), selected.getValue());
                     return new MatchResult(true, selected.getKey(), selected.getValue());
                 }
@@ -296,6 +326,19 @@ public class MatchService {
         }
     }
     
+    /**
+     * 清空匹配历史(实现循环匹配)
+     */
+    private void clearMatchedHistory(String userId) {
+        try {
+            String key = "match:history:" + userId;
+            redisTemplate.delete(key);
+            log.info("已清空匹配历史: userId={}", userId);
+        } catch (Exception e) {
+            log.warn("清空匹配历史失败: userId={}", userId, e);
+        }
+    }
+    
     /**
      * 从User和UserProfile构建MatchData
      */