|
@@ -3,23 +3,30 @@ package com.tzld.piaoquan.recommend.server.service.score4recall.strategy;
|
|
|
import com.tzld.piaoquan.recommend.server.service.score.ScorerConfigInfo;
|
|
|
import com.tzld.piaoquan.recommend.server.service.score4recall.AbstractScorer4Recall;
|
|
|
import com.tzld.piaoquan.recommend.server.service.score4recall.model4recall.Model4RecallKeyValue;
|
|
|
+import com.tzld.piaoquan.recommend.server.util.ListMerger;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
public class FestivalRecallScore extends AbstractScorer4Recall {
|
|
|
|
|
|
- private static final Map<String, List<String>> FESTIVAL_TIME_MAP = new HashMap<String, List<String>>() {
|
|
|
+ private static final Map<String, String> DAILY_BLESSING_TIME_MAP = new HashMap<String, String>() {
|
|
|
+ {
|
|
|
+ put("晚安", "daily 21:00-24:00");
|
|
|
+ put("晚上好", "daily 18:00-20:00");
|
|
|
+ put("下午好", "daily 15:00-16:00");
|
|
|
+ put("中午好 ", "daily 11:00-13:00");
|
|
|
+ put("早上好", "daily 00:00-08:00");
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private static final Map<String, List<String>> YEARLY_FESTIVAL_TIME_MAP = new HashMap<String, List<String>>() {
|
|
|
{
|
|
|
- put("晚安", Arrays.asList("daily 21:00-24:00"));
|
|
|
- put("晚上好", Arrays.asList("daily 18:00-20:00"));
|
|
|
- put("下午好", Arrays.asList("daily 15:00-16:00"));
|
|
|
- put("中午好 ", Arrays.asList("daily 11:00-13:00"));
|
|
|
- put("早上好", Arrays.asList("daily 00:00-08:00"));
|
|
|
put("圣诞节", Arrays.asList("2024-12-20 00:00~2024-12-25 08:00", "2025-12-20 00:00~2025-12-25 08:00", "2026-12-20 " +
|
|
|
"00:00~2026-12-25 08:00"));
|
|
|
put("平安夜", Arrays.asList("2024-12-19 00:00~2024-12-24 08:00", "2025-12-19 00:00~2025-12-24 08:00", "2026-12-19 " +
|
|
@@ -134,33 +141,86 @@ public class FestivalRecallScore extends AbstractScorer4Recall {
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public List<Pair<Long, Double>> recall(Map<String, String> params){
|
|
|
+ public List<Pair<Long, Double>> recall(Map<String, String> params) {
|
|
|
// 节假日、时效性,判断
|
|
|
Model4RecallKeyValue model = (Model4RecallKeyValue) this.getModel();
|
|
|
if (model == null || model.kv == null) {
|
|
|
return new ArrayList<>();
|
|
|
}
|
|
|
- List<Pair<Long, Double>> result = new ArrayList<>();
|
|
|
LocalDateTime now = LocalDateTime.now();
|
|
|
- for (Map.Entry<String, List<String>> entry : FESTIVAL_TIME_MAP.entrySet()) {
|
|
|
+ // 节日祝福-每年
|
|
|
+ List<Pair<Long, Double>> yearResult = new ArrayList<>();
|
|
|
+ for (Map.Entry<String, List<String>> entry : YEARLY_FESTIVAL_TIME_MAP.entrySet()) {
|
|
|
String festival = entry.getKey();
|
|
|
List<String> timeRangeList = entry.getValue();
|
|
|
if (isFestivalTime(now, timeRangeList)) {
|
|
|
+ Pair<LocalDateTime, LocalDateTime> startTimeAndEndTime = getStartTimeAndEndTime(timeRangeList.get(0));
|
|
|
+ if (startTimeAndEndTime == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // 节日峰值设置为结束时间的当天的9点
|
|
|
+ double weight = DynamicGaussianFunction.calculateValue(LocalDateTime.now(), startTimeAndEndTime.getLeft(),
|
|
|
+ startTimeAndEndTime.getRight(), startTimeAndEndTime.getRight().withHour(9));
|
|
|
+
|
|
|
+ List<Pair<Long, Double>> festivalLists = model.kv.getOrDefault(festival, new ArrayList<>());
|
|
|
+ if (festivalLists.isEmpty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ festivalLists = festivalLists.stream().map(pair -> Pair.of(pair.getLeft(), weight))
|
|
|
+ .limit(Math.min(50, festivalLists.size()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ yearResult.addAll(festivalLists);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<Pair<Long, Double>> dayResult = new ArrayList<>();
|
|
|
+ // 每日祝福-每天固定时间段
|
|
|
+ for (Map.Entry<String, String> entry : DAILY_BLESSING_TIME_MAP.entrySet()) {
|
|
|
+ String festival = entry.getKey();
|
|
|
+ String timeRange = entry.getValue();
|
|
|
+ if (isFestivalTime(now, Collections.singletonList(timeRange))) {
|
|
|
List<Pair<Long, Double>> festivalLists = model.kv.getOrDefault(festival, new ArrayList<>());
|
|
|
if (festivalLists.isEmpty()) {
|
|
|
continue;
|
|
|
}
|
|
|
- festivalLists = festivalLists.subList(0, Math.min(100, festivalLists.size()));
|
|
|
- result.addAll(festivalLists);
|
|
|
+ festivalLists = festivalLists.stream().map(pair -> Pair.of(pair.getLeft(), 0.0))
|
|
|
+ .limit(Math.min(50, festivalLists.size()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ dayResult.addAll(festivalLists);
|
|
|
}
|
|
|
}
|
|
|
- // 固定获取常规祝福类的小程序
|
|
|
+ // 常规祝福类的小程序-任意时间
|
|
|
+ List<Pair<Long, Double>> anyResult = new ArrayList<>();
|
|
|
List<Pair<Long, Double>> festivalLists = model.kv.getOrDefault("祝福", new ArrayList<>());
|
|
|
if (!festivalLists.isEmpty()) {
|
|
|
- festivalLists = festivalLists.subList(0, Math.min(100, festivalLists.size()));
|
|
|
- result.addAll(festivalLists);
|
|
|
+ festivalLists = festivalLists.stream().map(pair -> Pair.of(pair.getLeft(), 0.0))
|
|
|
+ .limit(Math.min(50, festivalLists.size()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ anyResult.addAll(festivalLists);
|
|
|
+ }
|
|
|
+ return ListMerger.mergeLists(yearResult, dayResult, anyResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ public Pair<LocalDateTime, LocalDateTime> getStartTimeAndEndTime(String timeRangeList) {
|
|
|
+ if (timeRangeList == null || timeRangeList.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 时间格式 2024-12-20 00:00~2024-12-25 08:00
|
|
|
+ if (StringUtils.startsWith(timeRangeList, "daily")) {
|
|
|
+ // 判断是否是 daily 开头
|
|
|
+ return null;
|
|
|
+ } else {
|
|
|
+ String[] split = StringUtils.split(timeRangeList, "~");
|
|
|
+ if (split.length != 2) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ String startTime = split[0];
|
|
|
+ String endTime = split[1];
|
|
|
+ // 解析 startTime endTime
|
|
|
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
|
|
|
+ LocalDateTime startLocalDateTime = LocalDateTime.parse(startTime, dateTimeFormatter);
|
|
|
+ LocalDateTime endLocalDateTime = LocalDateTime.parse(endTime, dateTimeFormatter);
|
|
|
+ return Pair.of(startLocalDateTime, endLocalDateTime);
|
|
|
}
|
|
|
- return result;
|
|
|
}
|
|
|
|
|
|
public boolean isFestivalTime(LocalDateTime now, List<String> timeRangeList) {
|