|
|
@@ -622,9 +622,10 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
private static final String CHANNEL_NAME_GZH = "公众号合作-即转-稳定";
|
|
|
private static final String CHANNEL_NAME_QW = "群/企微合作-稳定";
|
|
|
private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
|
|
|
- private static final String POSTERIOR_FILTER_ABS_LIKE = "绝对高效率%";
|
|
|
- private static final String POSTERIOR_FILTER_REL_LIKE = "相对裂变率%";
|
|
|
private static final String POSTERIOR_DRIVE_DIMENSION_TIME = "昨日";
|
|
|
+ /** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
|
|
|
+ * 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
|
|
|
+ private static final double POSTERIOR_GROUP_KEEP_RATIO = 0.5;
|
|
|
private static final String SOURCE_PRIOR = "prior";
|
|
|
private static final String SOURCE_POSTERIOR = "posterior";
|
|
|
private static final String SOURCE_HOT = "hot";
|
|
|
@@ -990,8 +991,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 优质相似池(posterior):A 段 "绝对高效率" → B 段 "相对裂变率"。
|
|
|
- * 每段按 demand_content_id 分组,组按 total_rov DESC、组内 score DESC 取前 K;段间拼接 + video_id 去重。
|
|
|
+ * 优质相似池(posterior):一段查询,不再按 demand_filter_sort_strategy 子分类。
|
|
|
+ * 按 demand_content_id 分组,组按 total_rov DESC、组内 score DESC 取前 K;
|
|
|
+ * 跨组用 video_id + 归一化标题去重,截到 limit。
|
|
|
*/
|
|
|
private List<VideoContentItemVO> fetchPosteriorCandidates(VideoContentListParam param, ContentPlatformAccount user, int limit) {
|
|
|
String dt = demandVideoMapperExt.getMaxDt();
|
|
|
@@ -1004,32 +1006,33 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
|
|
|
int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
|
|
|
|
|
|
String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
|
|
|
- List<ContentPlatformDemandVideo> stageAbs = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_ABS_LIKE, ghName, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
- List<ContentPlatformDemandVideo> stageRel = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_REL_LIKE, ghName, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
-
|
|
|
- // 退化:该 ghName 在两阶段都无数据 → 退回渠道粒度(drive_dimension_time 仍严格为"昨日")
|
|
|
- if (ghName != null && stageAbs.isEmpty() && stageRel.isEmpty()) {
|
|
|
- stageAbs = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_ABS_LIKE, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
- stageRel = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_REL_LIKE, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
+ // 公众号粒度(channel_level3 有值)时放开 drive_dimension_time:单公众号数据更稀疏,"昨日"窗口经常拿不到几条,
|
|
|
+ // 放宽为不限制能把"最近 15 日"那一档相似召回也带进来。渠道粒度兜底仍按"昨日"。
|
|
|
+ String stageDriveDimensionTime = (ghName != null) ? null : POSTERIOR_DRIVE_DIMENSION_TIME;
|
|
|
+ List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
|
|
|
+ dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, stageDriveDimensionTime, category, fetchLimit, true);
|
|
|
+
|
|
|
+ // 退化:该 ghName 无数据 → 退回渠道粒度(drive_dimension_time 仍严格为"昨日")
|
|
|
+ if (ghName != null && rows.isEmpty()) {
|
|
|
+ rows = demandVideoMapperExt.selectForRecommend(
|
|
|
+ dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
}
|
|
|
// 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
|
|
|
- if (channelName != null && stageAbs.isEmpty() && stageRel.isEmpty()) {
|
|
|
- stageAbs = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_ABS_LIKE, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
- stageRel = demandVideoMapperExt.selectForRecommend(
|
|
|
- dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, POSTERIOR_FILTER_REL_LIKE, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
+ if (channelName != null && rows.isEmpty()) {
|
|
|
+ rows = demandVideoMapperExt.selectForRecommend(
|
|
|
+ dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
|
|
|
}
|
|
|
|
|
|
Function<ContentPlatformDemandVideo, String> keyFn = r ->
|
|
|
r.getDemandContentId() == null ? "" : r.getDemandContentId();
|
|
|
|
|
|
- List<VideoContentItemVO> outAbs = groupAndTopK(stageAbs, keyFn, TOP_K_PER_DEMAND, true);
|
|
|
- List<VideoContentItemVO> outRel = groupAndTopK(stageRel, keyFn, TOP_K_PER_DEMAND, true);
|
|
|
- return concatDedup(outAbs, outRel, limit);
|
|
|
+ // 按 demand_content_id 的 total_rov 中位数过滤:保留中位数及以上(top 50%)的 demand 组,
|
|
|
+ // 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。
|
|
|
+ rows = retainTopGroupsByTotalRov(rows, keyFn, POSTERIOR_GROUP_KEEP_RATIO);
|
|
|
+
|
|
|
+ List<VideoContentItemVO> out = groupAndTopK(rows, keyFn, TOP_K_PER_DEMAND, true);
|
|
|
+ // 单段也要去归一化标题重复(同段内运营把同内容上传成多 video_id 的情况)
|
|
|
+ return concatDedup(out, Collections.emptyList(), limit);
|
|
|
}
|
|
|
|
|
|
/**
|