Use batchs for finding persons

This commit is contained in:
Mikhail Trofimov 2025-06-30 16:02:18 +03:00
parent 4af0bad507
commit e6859c5a8f
4 changed files with 103 additions and 27 deletions

View file

@ -9,7 +9,7 @@ import java.util.List;
@Mapper @Mapper
public interface PersonMapper { public interface PersonMapper {
PersonService.NameData findNameData(@Param("fid") Integer fid); List<PersonService.NameData> findNameData(@Param("fids") List<Integer> fids);
List<PersonService.PassportData> findPassportData(@Param("fid") Integer fid); List<PersonService.PassportData> findPassportData(@Param("fids") List<Integer> fids);
} }

View file

@ -124,18 +124,35 @@ public class SignalService {
Auth auth = new Auth(); Auth auth = new Auth();
auth.setUser(config.getSignalsuser()); auth.setUser(config.getSignalsuser());
signals.setAuth(auth); signals.setAuth(auth);
for (PhoneService.FidsPhoneData fidData : fids) { for (int i = 0; i < fids.size(); i += batchSize) {
Person person = findPerson(fidData.getFid(), fidData.getSubjectId()); int end = Math.min(i + batchSize, fids.size());
if (person != null) { List<Person> persons = findPersons(fids.subList(i, end));
signals.getConditions().getPersons().getPerson().add(person); if (!persons.isEmpty()) {
signals.getConditions().getPersons().getPerson().addAll(persons);
} }
} }
return signals; return signals;
} }
private Person findPerson(Integer fid, String id) { private List<Person> findPersons(List<PhoneService.FidsPhoneData> fidsPhoneData) {
PersonService.PersonData personData = personService.findPersonData(fid); List<Person> persons = new ArrayList<>();
Map<Integer, PersonService.PersonData> personFidMap = personService.findPersonData(fidsPhoneData.stream()
.map(PhoneService.FidsPhoneData::getFid)
.filter(Objects::nonNull).toList());
fidsPhoneData.forEach(data -> {
if (data.getFid() != null) {
PersonService.PersonData personData = personFidMap.get(data.getFid());
Person person = getPerson(personData, data.getSubjectId());
if (person != null) {
persons.add(person);
}
}
});
return persons;
}
private Person getPerson(PersonService.PersonData personData, String id) {
if (personData == null) { if (personData == null) {
return null; return null;
} }

View file

@ -10,7 +10,10 @@ import ru.nbch.credit_tracker.mapper.indic.PersonMapper;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Slf4j @Slf4j
@Service @Service
@ -22,22 +25,68 @@ public class PersonService {
this.mapper = mapper; this.mapper = mapper;
} }
public PersonData findPersonData(Integer fid) { public Map<Integer, PersonData> findPersonData(List<Integer> fids) {
NameData person = mapper.findNameData(fid); Map<Integer, PersonData> personDataMap = new HashMap<>();
PassportData passort = findPassportData(fid); Map<Integer, NameData> nameDataMap = findNameData(fids);
Map<Integer, PassportData> passortDataMap = findPassportData(fids);
fids.forEach(fid -> {
NameData person = nameDataMap.get(fid);
PassportData passort = passortDataMap.get(fid);
if (person != null && passort != null && requiredFieldPresent(person, passort)) { if (person != null && passort != null && requiredFieldPresent(person, passort)) {
return new PersonData(person, passort); personDataMap.put(fid, new PersonData(person, passort));
} else { } else {
log.warn("Person does not have required fields. Fid {}", fid); log.warn("Person does not have required fields. Fid {}", fid);
return null;
} }
});
return personDataMap;
} }
private PassportData findPassportData(Integer fid) {
List<PassportData> passports = mapper.findPassportData(fid);
List<PassportData> documents = passports.stream().filter(this::isDUL).toList(); // берем только ДУЛ private Map<Integer, NameData> findNameData(List<Integer> fids) {
List<NameData> persons = mapper.findNameData(fids);
return persons.stream()
.collect(Collectors.toMap(NameData::getFid, nameData -> nameData,
(existing, replacement) -> {
LocalDate existingDate = existing.getFileSinceDate();
LocalDate replacementDate = replacement.getFileSinceDate();
if (existingDate != null && replacementDate != null) {
if (existingDate.isAfter(replacementDate)) {
return existing;
} else {
return replacement;
}
} else if (existingDate != null) {
return existing;
} else {
return replacement;
}
}));
}
private Map<Integer, PassportData> findPassportData(List<Integer> fids) {
Map<Integer, PassportData> passportDataMap = new HashMap<>();
List<PassportData> passports = mapper.findPassportData(fids);
fids.forEach(fid -> {
PassportData passport = findPassport(passports.stream()
.filter(passportData -> passportData.getFid().equals(fid))
.collect(Collectors.toList()));
if (passport != null) {
passportDataMap.put(fid, passport);
}
});
return passportDataMap;
}
private PassportData findPassport(List<PassportData> passports) {
List<PassportData> documents = passports.stream()
.filter(this::isDUL)
.toList(); // берем только ДУЛ
if (documents.isEmpty()) { if (documents.isEmpty()) {
return null; return null;
@ -105,15 +154,18 @@ public class PersonService {
@Getter @Getter
@Setter @Setter
public static class NameData { public static class NameData {
private Integer fid;
private String firstName; private String firstName;
private String lastName; private String lastName;
private String middleName; private String middleName;
private LocalDate birthDate; private LocalDate birthDate;
private LocalDate fileSinceDate;
} }
@Getter @Getter
@Setter @Setter
public static class PassportData { public static class PassportData {
private Integer fid;
private String serNum; private String serNum;
private String idNum; private String idNum;
private LocalDate issDate; private LocalDate issDate;

View file

@ -6,13 +6,16 @@
<mapper namespace="ru.nbch.credit_tracker.mapper.indic.PersonMapper"> <mapper namespace="ru.nbch.credit_tracker.mapper.indic.PersonMapper">
<resultMap id="nameDataResultMap" type="ru.nbch.credit_tracker.service.indic.PersonService$NameData"> <resultMap id="nameDataResultMap" type="ru.nbch.credit_tracker.service.indic.PersonService$NameData">
<result property="fid" column="FID" />
<result property="firstName" column="FIRST" /> <result property="firstName" column="FIRST" />
<result property="lastName" column="NAME_1" /> <result property="lastName" column="NAME_1" />
<result property="middleName" column="MIDDLE" /> <result property="middleName" column="MIDDLE" />
<result property="birthDate" column="BIRTH_DT" /> <result property="birthDate" column="BIRTH_DT" />
<result property="fileSinceDate" column="FILE_SINCE_DT" />
</resultMap> </resultMap>
<resultMap id="passportDataResultMap" type="ru.nbch.credit_tracker.service.indic.PersonService$PassportData"> <resultMap id="passportDataResultMap" type="ru.nbch.credit_tracker.service.indic.PersonService$PassportData">
<result property="fid" column="FID" />
<result property="serNum" column="SER_NUM" /> <result property="serNum" column="SER_NUM" />
<result property="idNum" column="ID_NUM" /> <result property="idNum" column="ID_NUM" />
<result property="issDate" column="ISS_DTE" /> <result property="issDate" column="ISS_DTE" />
@ -22,17 +25,21 @@
</resultMap> </resultMap>
<select id="findNameData" resultMap="nameDataResultMap"> <select id="findNameData" resultMap="nameDataResultMap">
SELECT FIRST, NAME_1, MIDDLE, BIRTH_DT SELECT FID, FIRST, NAME_1, MIDDLE, BIRTH_DT, FILE_SINCE_DT
FROM NAME FROM NAME
WHERE FID = #{fid} WHERE FID IN
ORDER BY FILE_SINCE_DT DESC <foreach item="fid" collection="fids" open="(" separator="," close=")">
LIMIT 1 #{fid}
</foreach>
</select> </select>
<select id="findPassportData" resultMap="passportDataResultMap" resultType="java.util.List"> <select id="findPassportData" resultMap="passportDataResultMap" resultType="java.util.List">
SELECT SER_NUM, ID_NUM, ISS_DTE, FILE_SINCE_DT, ID_TYPE, ID_TYPE2 SELECT FID, SER_NUM, ID_NUM, ISS_DTE, FILE_SINCE_DT, ID_TYPE, ID_TYPE2
FROM ID FROM ID
WHERE FID = #{fid} WHERE FID IN
<foreach item="fid" collection="fids" open="(" separator="," close=")">
#{fid}
</foreach>
</select> </select>
</mapper> </mapper>