fix: 优化鱼类智能查询

This commit is contained in:
tangwei 2026-04-29 11:52:20 +08:00
parent de0a291f70
commit 1239b58fee
4 changed files with 100 additions and 69 deletions

View File

@ -1,5 +1,6 @@
package com.yfd.platform.env.service.impl; package com.yfd.platform.env.service.impl;
import cn.hutool.core.util.ObjectUtil;
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.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -72,106 +73,136 @@ public class SdFishDictoryBServiceImpl extends ServiceImpl<SdFishDictoryBMapper,
return Collections.emptyList(); return Collections.emptyList();
} }
int resultLimit = (limit != null && limit > 0) ? limit : 10;
String searchName = name.trim(); String searchName = name.trim();
LambdaQueryWrapper<SdFishDictoryB> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SdFishDictoryB> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(SdFishDictoryB::getIsDeleted, 0); wrapper.eq(SdFishDictoryB::getIsDeleted, 0);
List<SdFishDictoryB> allFish = list(wrapper); List<SdFishDictoryB> allFish = list(wrapper);
SdFishDictoryB referenceFish = allFish.stream() SdFishDictoryB exactMatch = allFish.stream()
.filter(f -> f.getName() != null && f.getName().equals(searchName)) .filter(f -> f.getName() != null && f.getName().equals(searchName))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (referenceFish == null) { if (exactMatch != null) {
referenceFish = allFish.stream() Map<SdFishDictoryB, Integer> similarityMap = new HashMap<>();
.filter(f -> f.getName() != null && f.getName().contains(searchName)) for (SdFishDictoryB fish : allFish) {
.findFirst() if (fish.getId().equals(exactMatch.getId())) {
.orElse(null); continue;
} }
int score = calculateSimilarity(exactMatch, fish);
if (score > 0) {
similarityMap.put(fish, score);
}
}
if (referenceFish == null && allFish.stream().anyMatch(f -> List<SdFishDictoryB> result = similarityMap.entrySet().stream()
f.getName() != null && (f.getName().contains(searchName) || searchName.contains(f.getName())))) { .sorted(Map.Entry.<SdFishDictoryB, Integer>comparingByValue().reversed())
final String searchNameFinal = searchName; .limit(resultLimit)
referenceFish = allFish.stream() .map(Map.Entry::getKey)
.filter(f -> f.getName() != null &&
(f.getName().contains(searchNameFinal) || searchNameFinal.contains(f.getName())))
.findFirst()
.orElse(null);
}
if (referenceFish == null) {
return allFish.stream()
.filter(f -> f.getName() != null && f.getName().contains(searchName))
.limit(limit != null ? limit : 10)
.collect(Collectors.toList()); .collect(Collectors.toList());
result.add(0, exactMatch);
return result;
} }
final SdFishDictoryB finalRefFish = referenceFish; List<SdFishDictoryB> containsMatches = allFish.stream()
Map<SdFishDictoryB, Integer> similarityMap = new HashMap<>(); .filter(f -> f.getName() != null && f.getName().contains(searchName))
for (SdFishDictoryB fish : allFish) {
if (fish.getId().equals(finalRefFish.getId())) {
continue;
}
int score = calculateSimilarity(finalRefFish, fish);
if (score > 0) {
similarityMap.put(fish, score);
}
}
return similarityMap.entrySet().stream()
.sorted(Map.Entry.<SdFishDictoryB, Integer>comparingByValue().reversed())
.limit(limit != null ? limit : 10)
.map(Map.Entry::getKey)
.collect(Collectors.toList()); .collect(Collectors.toList());
if (!containsMatches.isEmpty()) {
List<SdFishDictoryB> result = containsMatches.stream()
.sorted((f1, f2) -> {
int len1 = f1.getName().length();
int len2 = f2.getName().length();
if (len1 != len2) {
return Integer.compare(len1, len2);
}
return f1.getName().compareTo(f2.getName());
})
.limit(resultLimit)
.collect(Collectors.toList());
return result;
}
SdFishDictoryB partialMatch = allFish.stream()
.filter(f -> f.getName() != null && (searchName.contains(f.getName()) || f.getName().contains(searchName)))
.findFirst()
.orElse(null);
if (partialMatch != null) {
Map<SdFishDictoryB, Integer> similarityMap = new HashMap<>();
for (SdFishDictoryB fish : allFish) {
if (fish.getId().equals(partialMatch.getId())) {
continue;
}
int score = calculateSimilarity(partialMatch, fish);
if (score > 0) {
similarityMap.put(fish, score);
}
}
List<SdFishDictoryB> result = similarityMap.entrySet().stream()
.sorted(Map.Entry.<SdFishDictoryB, Integer>comparingByValue().reversed())
.limit(resultLimit)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
result.add(0, partialMatch);
return result;
}
return Collections.emptyList();
} }
private int calculateSimilarity(SdFishDictoryB ref, SdFishDictoryB target) { private int calculateSimilarity(SdFishDictoryB ref, SdFishDictoryB target) {
int score = 0; int score = 0;
if (ref.getOrders() != null && ref.getOrders().equals(target.getOrders())) { if (ref.getGenus() != null && ref.getGenus().equals(target.getGenus()) && !ref.getGenus().isEmpty()) {
score += 3; score += 25;
} }
if (ref.getFamily() != null && ref.getFamily().equals(target.getFamily())) {
score += 5; if (ref.getSpecies() != null && ref.getSpecies().equals(target.getSpecies()) && !ref.getSpecies().isEmpty()) {
score += 20;
} }
if (ref.getGenus() != null && ref.getGenus().equals(target.getGenus())) {
score += 8; if (ref.getFamily() != null && ref.getFamily().equals(target.getFamily()) && !ref.getFamily().isEmpty()) {
score += 15;
} }
if (ref.getSpecies() != null && ref.getSpecies().equals(target.getSpecies())) {
if (ref.getOrders() != null && ref.getOrders().equals(target.getOrders()) && !ref.getOrders().isEmpty()) {
score += 10; score += 10;
} }
if (ref.getType() != null && ref.getType().equals(target.getType())) { if (ref.getType() != null && ref.getType().equals(target.getType()) && !ObjectUtil.isEmpty(ref.getType()) ) {
score += 2; score += 5;
} }
if (ref.getHabitat() != null && ref.getHabitat().equals(target.getHabitat())) { if (ref.getHabitat() != null && ref.getHabitat().equals(target.getHabitat()) && !ObjectUtil.isEmpty(ref.getHabitat())) {
score += 5;
}
if (ref.getHabitMigrat() != null && ref.getHabitMigrat().equals(target.getHabitMigrat()) && !ref.getHabitMigrat().isEmpty()) {
score += 5;
}
if (ref.getFeedingHabit() != null && ref.getFeedingHabit().equals(target.getFeedingHabit()) && !ref.getFeedingHabit().isEmpty()) {
score += 3; score += 3;
} }
if (ref.getRare() != null && ref.getRare().equals(target.getRare())) { if (ref.getSpawnCharact() != null && ref.getSpawnCharact().equals(target.getSpawnCharact()) && !ref.getSpawnCharact().isEmpty()) {
score += 2;
}
if (ref.getPtype() != null && ref.getPtype().equals(target.getPtype())) {
score += 2;
}
if (ref.getResourceType() != null && ref.getResourceType().equals(target.getResourceType())) {
score += 2;
}
if (ref.getHabitMigrat() != null && ref.getHabitMigrat().equals(target.getHabitMigrat())) {
score += 3; score += 3;
} }
if (ref.getFeedingHabit() != null && ref.getFeedingHabit().equals(target.getFeedingHabit())) { if (ref.getPtype() != null && ref.getPtype().equals(target.getPtype()) && !ObjectUtil.isEmpty(ref.getPtype())) {
score += 2; score += 2;
} }
if (ref.getSpawnCharact() != null && ref.getSpawnCharact().equals(target.getSpawnCharact())) { if (ref.getResourceType() != null && ref.getResourceType().equals(target.getResourceType()) && !ObjectUtil.isEmpty(ref.getResourceType())) {
score += 2;
}
if (ref.getRare() != null && ref.getRare().equals(target.getRare()) && !ObjectUtil.isEmpty(ref.getRare())) {
score += 2; score += 2;
} }

View File

@ -10,12 +10,12 @@ spring:
druid: druid:
master: master:
driverClassName: oracle.jdbc.OracleDriver driverClassName: oracle.jdbc.OracleDriver
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}" username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}" password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
slave: slave:
driverClassName: oracle.jdbc.OracleDriver driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}" username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}" password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"

View File

@ -10,12 +10,12 @@ spring:
druid: druid:
master: master:
driverClassName: oracle.jdbc.OracleDriver driverClassName: oracle.jdbc.OracleDriver
url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" url: "${DB_MASTER_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_MASTER_USERNAME:QGC_REFA}" username: "${DB_MASTER_USERNAME:QGC_REFA}"
password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}" password: "${DB_MASTER_PASSWORD:Y4M4K1oCkL8U}"
slave: slave:
driverClassName: oracle.jdbc.OracleDriver driverClassName: oracle.jdbc.OracleDriver
url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.21.134:1521/SDLYZ}" url: "${DB_SLAVE_URL:jdbc:oracle:thin:@172.16.31.190:1521/SDLYZ}"
username: "${DB_SLAVE_USERNAME:QGC_REFA}" username: "${DB_SLAVE_USERNAME:QGC_REFA}"
password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}" password: "${DB_SLAVE_PASSWORD:Y4M4K1oCkL8U}"

View File

@ -1,6 +1,6 @@
spring: spring:
profiles: profiles:
active: devtw active: prod
jasypt: jasypt:
encryptor: encryptor: