Optimize fids loading

This commit is contained in:
Mikhail Trofimov 2025-06-26 16:28:57 +03:00
parent 656ca4172e
commit d6992e00c0
5 changed files with 74 additions and 18 deletions

View file

@ -2,8 +2,11 @@ package ru.nbch.credit_tracker.mapper.indic;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import ru.nbch.credit_tracker.service.indic.PhoneService;
import java.util.List;
@Mapper @Mapper
public interface PhoneMapper { public interface PhoneMapper {
Integer findFidByNumber(@Param("phone") String phone); List<PhoneService.FidsData> findFids(@Param("phones") List<String> phones);
} }

View file

@ -57,7 +57,12 @@ public class SignalService {
public Integer registerPackage(MonitoringRequest request) { public Integer registerPackage(MonitoringRequest request) {
Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name()); Integer packageId = mapper.registerPackage(request, LocalDateTime.now(), Status.PROCESSING.name());
mapper.registerSubjects(request.getSubjects().getSubject(), packageId); int batchSize = 10000;
List<Subject> subjects = request.getSubjects().getSubject();
for (int i = 0; i < subjects.size(); i += batchSize) {
int end = Math.min(i + batchSize, subjects.size());
mapper.registerSubjects(subjects.subList(i, end), packageId);
}
return packageId; return packageId;
} }

View file

@ -28,6 +28,7 @@ public class FlagsService {
flagsData.setFlag90days(calcFlag90Days(fid)); flagsData.setFlag90days(calcFlag90Days(fid));
return flagsData; return flagsData;
} }
/** /**
* По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT. * По FID из RU_PASTDUEARREAR выбираются все уникальные ACC_SERIAL_NUM с максимальной датой REPORTED_DT.
* Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то флаг устанавливается в 1. * Если по хотя бы одной такой записи AMT_PAST_DUE > 5000, то флаг устанавливается в 1.
@ -45,7 +46,11 @@ public class FlagsService {
.map(Optional::get) .map(Optional::get)
.toList(); .toList();
if (!dataList.isEmpty() && dataList.stream().anyMatch(item -> item != null && item.getAmountPastDue() != null && item.getAmountPastDue().compareTo(BigDecimal.valueOf(5000)) > 0)) { if (!dataList.isEmpty() && dataList.stream()
.anyMatch(item ->
item != null && item.getAmountPastDue() != null &&
item.getAmountPastDue().compareTo(BigDecimal.valueOf(5000)) > 0)
) {
return 1; return 1;
} else { } else {
return 0; return 0;

View file

@ -7,8 +7,9 @@ import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.entities.dto.SubjectData; import ru.nbch.credit_tracker.entities.dto.SubjectData;
import ru.nbch.credit_tracker.mapper.indic.PhoneMapper; import ru.nbch.credit_tracker.mapper.indic.PhoneMapper;
import java.util.ArrayList; import java.time.LocalDate;
import java.util.List; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
public class PhoneService { public class PhoneService {
@ -25,18 +26,44 @@ public class PhoneService {
public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) { public List<FidsPhoneData> findFidsPhoneData(List<SubjectData> subjects, boolean processNullFids) {
List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>(); List<FidsPhoneData> fidsPhoneDataList = new ArrayList<>();
subjects.forEach(subject -> { int batchSize = 10000;
for (int i = 0; i < subjects.size(); i += batchSize) {
int end = Math.min(i + batchSize, subjects.size());
List<SubjectData> currentSubjects = subjects.subList(i, end);
List<FidsData> fidsData = mapper.findFids(currentSubjects.stream().map(subject -> "9" + subject.getPhone()).toList());
Map<String, Integer> fidsMap = convertFidsDataToMap(fidsData);
currentSubjects.forEach(subject -> {
String phone = "9" + subject.getPhone(); String phone = "9" + subject.getPhone();
Integer fid = mapper.findFidByNumber(phone); Integer fid = fidsMap.get(phone);
if (fid != null) { if (fid != null) {
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, phone, subject.getSubjectId())); fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), fid, phone, subject.getSubjectId()));
} else if (processNullFids) { } else if (processNullFids) {
fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), null, phone, subject.getSubjectId())); fidsPhoneDataList.add(new FidsPhoneData(subject.getId(), null, phone, subject.getSubjectId()));
} }
}); });
}
return fidsPhoneDataList; return fidsPhoneDataList;
} }
private Map<String, Integer> convertFidsDataToMap(List<FidsData> fidsData) {
if (fidsData == null || fidsData.isEmpty()) {
return new HashMap<>();
}
return fidsData.stream()
.collect(Collectors.groupingBy(
FidsData::getPhone,
Collectors.collectingAndThen(
Collectors.maxBy(
Comparator.comparing(FidsData::getFileSinceDate)
.thenComparing(FidsData::getFid)
),
data -> data.map(FidsData::getFid).orElse(null)
)
));
}
@Getter @Getter
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
@ -46,4 +73,12 @@ public class PhoneService {
private String phone; private String phone;
private String subjectId; private String subjectId;
} }
@Getter
@Setter
public static class FidsData {
private Integer fid;
private String phone;
private LocalDate fileSinceDate;
}
} }

View file

@ -5,11 +5,19 @@
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.PhoneMapper"> <mapper namespace="ru.nbch.credit_tracker.mapper.indic.PhoneMapper">
<select id="findFidByNumber" resultType="java.lang.Integer"> <resultMap id="fidsDataResultMap" type="ru.nbch.credit_tracker.service.indic.PhoneService$FidsData">
SELECT FID <result property="phone" column="NUMBER" />
<result property="fid" column="FID" />
<result property="fileSinceDate" column="FILE_SINCE_DT" />
</resultMap>
<select id="findFids" resultMap="fidsDataResultMap" parameterType="java.util.List" resultType="ru.nbch.credit_tracker.service.indic.PhoneService$FidsData">
SELECT NUMBER, FID, FILE_SINCE_DT
FROM PHONE_NORM FROM PHONE_NORM
WHERE NUMBER = #{phone} WHERE NUMBER in
<foreach item='phone' collection='phones' open='(' separator=',' close=')'>
#{phone}
</foreach>
ORDER BY FILE_SINCE_DT DESC, FID DESC ORDER BY FILE_SINCE_DT DESC, FID DESC
LIMIT 1
</select> </select>
</mapper> </mapper>