|
@@ -58,27 +58,37 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
|
|
|
// recordKey: 每小时生成一个召回源,用来决定用哪个召回源
|
|
|
// poolKey: 召回源的key
|
|
|
// lastVideoLKey: 上次返回的最后一个视频
|
|
|
+ /**
|
|
|
+ * 1、如果当前小时数据已生成,那么召回源用当前小时数据
|
|
|
+ * 2、如果当前小时数据未生成,那么召回源用前一小时数据
|
|
|
+ *
|
|
|
+ * 1、如果recordKey是当前小时数据,用lastVideo作为cursor
|
|
|
+ * 2、如果recordKey是前一小时数据,重置lastVideo
|
|
|
+ *
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
String record = redisTemplate.opsForValue().get(recordKey);
|
|
|
if (StringUtils.isNotBlank(record)) {
|
|
|
Map<String, String> recordMap = JSONUtils.fromJson(record, new TypeToken<Map<String, String>>() {
|
|
|
}, Collections.emptyMap());
|
|
|
if (MapUtils.isNotEmpty(recordMap)) {
|
|
|
String record_dt = recordMap.get("date");
|
|
|
- String record_h = recordMap.get("h");
|
|
|
+ int record_h = NumberUtils.toInt(recordMap.get("h"), 0);
|
|
|
String now_dt = DateUtils.getCurrentDateStr("yyyyMMdd");
|
|
|
int h = DateUtils.getCurrentHour();
|
|
|
- if (record_dt.equals(now_dt) && Integer.parseInt(record_h) == h) {
|
|
|
- poolKey = poolKey(param, now_dt, h);
|
|
|
+ if (record_dt.equals(now_dt) && record_h == h) {
|
|
|
+ poolKey = poolKey(param, record_dt, record_h);
|
|
|
idx = getIdx(lastVideoKey, poolKey);
|
|
|
- } else if ((record_dt.equals(now_dt) && h - Integer.parseInt(record_h) == 1)
|
|
|
- || (h == 0 && Integer.parseInt(record_h) == 23)) {
|
|
|
+ } else if ((record_dt.equals(now_dt) && h - record_h == 1)
|
|
|
+ || (h == 0 && record_h == 23)) {
|
|
|
poolKey = poolKey(param, now_dt, h);
|
|
|
if (redisTemplate.hasKey(poolKey)) {
|
|
|
redisTemplate.opsForValue().set(recordKey, String.format(recordKeyFormat, now_dt,
|
|
|
h), 2, TimeUnit.HOURS);
|
|
|
redisTemplate.delete(lastVideoKey);
|
|
|
} else {
|
|
|
- poolKey = poolKey(param, record_dt, Integer.parseInt(record_h));
|
|
|
+ poolKey = poolKey(param, record_dt, record_h);
|
|
|
idx = getIdx(lastVideoKey, poolKey);
|
|
|
}
|
|
|
} else {
|
|
@@ -134,9 +144,11 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 如果不限制返回size个数据,可以迁移到排序阶段
|
|
|
+ // Collections.sort(results, Comparator.comparingDouble(o -> -o.getRovScore()));
|
|
|
|
|
|
- Collections.sort(results, Comparator.comparingDouble(o -> -o.getRovScore()));
|
|
|
-
|
|
|
+ // 这里是一个优化:如果所有数据都被过滤,说明下一次召回可以直接从lastVideo开始
|
|
|
+ // TODO 可以优化成异步更新
|
|
|
if (StringUtils.isNotBlank(lastVideoId)
|
|
|
&& CollectionUtils.isEmpty(results)
|
|
|
&& StringUtils.isNotBlank(param.getMid())) {
|
|
@@ -144,7 +156,8 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
|
|
|
redisTemplate.opsForValue().set(lastVideoKey, lastVideoId, 2, TimeUnit.HOURS);
|
|
|
}
|
|
|
|
|
|
- return results.subList(0, results.size() < param.getSize() ? results.size() : param.getSize());
|
|
|
+ // return results.subList(0, results.size() < param.getSize() ? results.size() : param.getSize());
|
|
|
+ return results;
|
|
|
}
|
|
|
|
|
|
private int getIdx(String lastVideoKey, String poolKey) {
|
|
@@ -160,7 +173,6 @@ public abstract class AbstractRegionRecallStrategy implements RecallStrategy {
|
|
|
return idx;
|
|
|
}
|
|
|
|
|
|
- // TODO 和 推荐排序后的lastVideo更新有什么区别?
|
|
|
private String updateLastVideoRecord(String recordKey, RecallParam param) {
|
|
|
String currentDateStr = DateUtils.getCurrentDateStr("yyyyMMdd");
|
|
|
int h = DateUtils.getCurrentHour();
|