Browse Source

优化打分 内存溢出问题

master
kami 1 year ago
parent
commit
0cbc3ae77b
  1. 99
      src/main/java/com/biutag/supervisiondata/service/impl/RiskScoreRuleServiceImpl.java

99
src/main/java/com/biutag/supervisiondata/service/impl/RiskScoreRuleServiceImpl.java

@ -1,10 +1,6 @@
package com.biutag.supervisiondata.service.impl; package com.biutag.supervisiondata.service.impl;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.biutag.supervisiondata.config.cache.RedisDao;
import com.biutag.supervisiondata.pojo.constants.RedisKey;
import com.biutag.supervisiondata.pojo.entity.mine.Model; import com.biutag.supervisiondata.pojo.entity.mine.Model;
import com.biutag.supervisiondata.pojo.entity.mine.RiskModelTaskClue; import com.biutag.supervisiondata.pojo.entity.mine.RiskModelTaskClue;
import com.biutag.supervisiondata.pojo.entity.mine.RiskPersonal; import com.biutag.supervisiondata.pojo.entity.mine.RiskPersonal;
@ -13,8 +9,6 @@ import com.biutag.supervisiondata.repository.ModelRepository;
import com.biutag.supervisiondata.repository.RiskModelTaskClueRepository; import com.biutag.supervisiondata.repository.RiskModelTaskClueRepository;
import com.biutag.supervisiondata.repository.RiskPersonalRepository; import com.biutag.supervisiondata.repository.RiskPersonalRepository;
import com.biutag.supervisiondata.repository.RiskScoreRuleRepository; import com.biutag.supervisiondata.repository.RiskScoreRuleRepository;
import com.biutag.supervisiondata.service.RiskPersonalControlRecordService;
import com.biutag.supervisiondata.service.RiskPersonalService;
import com.biutag.supervisiondata.service.RiskScoreRuleService; import com.biutag.supervisiondata.service.RiskScoreRuleService;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -25,6 +19,7 @@ import java.math.RoundingMode;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream;
/** /**
* @author kami on 2024-11-18 19:38:10 * @author kami on 2024-11-18 19:38:10
@ -48,7 +43,7 @@ public class RiskScoreRuleServiceImpl implements RiskScoreRuleService {
public void runScore(List<String> idCodes, String weight) { public void runScore(List<String> idCodes, String weight) {
LambdaQueryWrapper<RiskPersonal> queryWrapper = new LambdaQueryWrapper<RiskPersonal>() LambdaQueryWrapper<RiskPersonal> queryWrapper = new LambdaQueryWrapper<RiskPersonal>()
.select(RiskPersonal::getIdCode, RiskPersonal::getId, RiskPersonal::getRickScore); .select(RiskPersonal::getIdCode, RiskPersonal::getId, RiskPersonal::getRickScore);
if(idCodes != null && !idCodes.isEmpty()) { if (idCodes != null && !idCodes.isEmpty()) {
queryWrapper.in(RiskPersonal::getIdCode, idCodes); queryWrapper.in(RiskPersonal::getIdCode, idCodes);
} }
@ -62,93 +57,73 @@ public class RiskScoreRuleServiceImpl implements RiskScoreRuleService {
.select(Model::getId, Model::getRiskScoreRuleId)); .select(Model::getId, Model::getRiskScoreRuleId));
Map<Integer, Model> modelMap = models.stream().collect(Collectors.toMap(Model::getRiskScoreRuleId, Function.identity(), (oldValue, newValue) -> newValue)); Map<Integer, Model> modelMap = models.stream().collect(Collectors.toMap(Model::getRiskScoreRuleId, Function.identity(), (oldValue, newValue) -> newValue));
List<RiskModelTaskClue> clues = riskModelTaskClueRepository.list(new LambdaQueryWrapper<RiskModelTaskClue>() List<List<RiskPersonal>> personals = IntStream.range(0, (riskPersonals.size() + 99999) / 100000)
.select(RiskModelTaskClue::getId, RiskModelTaskClue::getScoreCalc) .mapToObj(i -> riskPersonals.subList(i * 100000, Math.min((i + 1) * 100000, riskPersonals.size())))
.toList();
log.info("本次打分将对{}人进行算分,分{}批进行", riskPersonals.size(), personals);
calc(personals, weight, rulesV1, ruleMap, modelMap);
}
void calc(List<List<RiskPersonal>> personals, String weight, List<RiskScoreRule> rulesV1, Map<Integer, List<RiskScoreRule>> ruleMap, Map<Integer, Model> modelMap) {
List<RiskModelTaskClue> clues;
List<RiskModelTaskClue> updates;
for (int i = 0; i < personals.size(); i++) {
List<String> idCodes = personals.get(i).stream().map(RiskPersonal::getIdCode).distinct().toList();
clues = riskModelTaskClueRepository.list(new LambdaQueryWrapper<RiskModelTaskClue>()
.select(RiskModelTaskClue::getId, RiskModelTaskClue::getIdCode, RiskModelTaskClue::getModelId, RiskModelTaskClue::getScoreCalc)
.in(RiskModelTaskClue::getIdCode, idCodes)
.eq(RiskModelTaskClue::getDel, 0)); .eq(RiskModelTaskClue::getDel, 0));
log.info("计算分项倍分"); log.info("第{}批总风险项{}条", i, clues.size());
List<RiskModelTaskClue> updates = new ArrayList<>(); updates = new ArrayList<>();
if(weight != null && !weight.equals("1")) {
for (RiskModelTaskClue clue : clues) { for (RiskModelTaskClue clue : clues) {
RiskModelTaskClue update = new RiskModelTaskClue(); RiskModelTaskClue update = new RiskModelTaskClue();
update.setId(clue.getId()); update.setId(clue.getId());
update.setScoreResult(new BigDecimal(clue.getScoreCalc().toString()).multiply(new BigDecimal(weight)).divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP).doubleValue()); update.setScoreResult(new BigDecimal(clue.getScoreCalc().toString()).multiply(new BigDecimal(weight)).divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP).doubleValue());
updates.add(update); updates.add(update);
clue.setScoreResult(update.getScoreResult());
} }
log.info("修改每项得分"); log.info("第{}批修改得分数量{}条", i, updates.size());
riskModelTaskClueRepository.updateBatchById(updates, 100000); riskModelTaskClueRepository.updateBatchById(updates, 100000);
}
clues = riskModelTaskClueRepository.list(new LambdaQueryWrapper<RiskModelTaskClue>()
.select(RiskModelTaskClue::getIdCode, RiskModelTaskClue::getModelId, RiskModelTaskClue::getScoreResult)
.eq(RiskModelTaskClue::getDel, 0));
log.info("开始算分");
log.info("第{}批开始算分", i);
Map<String, Map<Integer, List<RiskModelTaskClue>>> clueMap = new HashMap<>(); Map<String, Map<Integer, List<RiskModelTaskClue>>> clueMap = new HashMap<>();
for (RiskModelTaskClue clue : clues) { clues.forEach(clue -> clueMap
Map<Integer, List<RiskModelTaskClue>> tmp = Optional.ofNullable(clueMap.get(clue.getIdCode())).orElse(new HashMap<>()); .computeIfAbsent(clue.getIdCode(), k -> new HashMap<>()) // 获取或初始化内部 Map
List<RiskModelTaskClue> list = Optional.ofNullable(tmp.get(clue.getModelId())).orElse(new ArrayList<>()); .computeIfAbsent(clue.getModelId(), k -> new ArrayList<>()) // 获取或初始化 List
list.add(clue); .add(clue));
tmp.put(clue.getModelId(), list);
clueMap.put(clue.getIdCode(), tmp);
}
List<RiskPersonal> toUpdates = new ArrayList<>(); List<RiskPersonal> toUpdates = new ArrayList<>();
int count = 0;
int size = riskPersonals.size();
RiskPersonal update; RiskPersonal update;
for (RiskPersonal person : riskPersonals) { for (RiskPersonal person : personals.get(i)) {
BigDecimal total = new BigDecimal("0.0"); BigDecimal total = BigDecimal.ZERO;
for (RiskScoreRule rule : rulesV1) { for (RiskScoreRule rule : rulesV1) {
List<RiskScoreRule> r = Optional.ofNullable(ruleMap.get(rule.getId())).orElse(new ArrayList<>()); List<RiskScoreRule> r = Optional.ofNullable(ruleMap.get(rule.getId())).orElse(new ArrayList<>());
BigDecimal score = new BigDecimal("0.00"); BigDecimal score = BigDecimal.ZERO;
for (RiskScoreRule riskScoreRule : r) { for (RiskScoreRule riskScoreRule : r) {
Model model = modelMap.get(riskScoreRule.getId()); Model model = modelMap.get(riskScoreRule.getId());
if(model == null) {
continue;
}
Map<Integer, List<RiskModelTaskClue>> tmp = clueMap.get(person.getIdCode()); Map<Integer, List<RiskModelTaskClue>> tmp = clueMap.get(person.getIdCode());
if(tmp == null) { if (tmp == null || model == null) {
continue; continue;
} }
List<RiskModelTaskClue> temp = tmp.get(model.getId()); List<RiskModelTaskClue> temp = tmp.get(model.getId());
if(temp == null) { if (temp == null) {
continue; continue;
} }
double ruleScore = temp.stream().mapToDouble(RiskModelTaskClue::getScoreResult).sum();
//二次改造
// Integer ruleScore = temp.stream().mapToInt(RiskModelTaskClue::getScore).sum();
// BigDecimal n2 = new BigDecimal(Double.toString(Math.min(ruleScore.doubleValue(), riskScoreRule.getScore())));
//
// BigDecimal weight = new BigDecimal(Double.toString(riskScoreRule.getWeight()));
// n2 = n2.multiply(weight).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
Double ruleScore = temp.stream().mapToDouble(RiskModelTaskClue::getScoreResult).sum();
BigDecimal rScore = new BigDecimal(riskScoreRule.getScore().toString()).multiply(new BigDecimal(weight)).divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP); BigDecimal rScore = new BigDecimal(riskScoreRule.getScore().toString()).multiply(new BigDecimal(weight)).divide(new BigDecimal("1"), 2, RoundingMode.HALF_UP);
BigDecimal n2 = new BigDecimal(Double.toString(Math.min(ruleScore, rScore.doubleValue()))); BigDecimal n2 = new BigDecimal(Double.toString(Math.min(ruleScore, rScore.doubleValue())));
score=score.add(n2); score = score.add(n2);
} }
// BigDecimal ruleScore = new BigDecimal(Double.toString(rule.getScore()));
// BigDecimal weight = new BigDecimal(Double.toString(rule.getWeight()));
// score = score.multiply(weight).divide(ruleScore, 2, RoundingMode.HALF_UP);
total = total.add(score); total = total.add(score);
} }
//二次改造
// total = total.multiply(new BigDecimal("20"));
if(person.getRickScore() == null || person.getRickScore().compareTo(total.doubleValue()) != 0) {
update = new RiskPersonal(); update = new RiskPersonal();
update.setId(person.getId()); update.setId(person.getId());
update.setRickScore(total.doubleValue()); update.setRickScore(total.doubleValue());
update.setDel(total.doubleValue() <= 0.0?1:0);
toUpdates.add(update); toUpdates.add(update);
} }
if(total.doubleValue() <= 0.0) { log.info("第{}批完成打分完成,共计:{}", i, toUpdates.size());
update = new RiskPersonal();
update.setId(person.getId());
update.setDel(1);
toUpdates.add(update);
}
count++;
if(count%100000 == 0) {
log.info("已完成打分: {},共计:{}", count,size);
}
}
personalRepository.updateBatchById(toUpdates, 10000); personalRepository.updateBatchById(toUpdates, 10000);
} }
}
} }

Loading…
Cancel
Save