Bläddra i källkod

Merge branch 'cooperation_video_candidate_pool_improved_lld_0509' into test

刘立冬 4 timmar sedan
förälder
incheckning
4878c45f60

+ 16 - 13
api-module/src/main/java/com/tzld/piaoquan/api/service/contentplatform/impl/ContentPlatformPlanServiceImpl.java

@@ -614,14 +614,14 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
     private static final String DEMAND_STRATEGY_PRIOR_SCENE = "人群需求-场景";
     private static final String DEMAND_STRATEGY_PRIOR_SCENE = "人群需求-场景";
     private static final String DEMAND_STRATEGY_POSTERIOR = "优质相似";
     private static final String DEMAND_STRATEGY_POSTERIOR = "优质相似";
     private static final String PRIOR_PREMIUM_DIMENSION = "传播的头部";
     private static final String PRIOR_PREMIUM_DIMENSION = "传播的头部";
-    /** prior 池视频近 7 日 rov 下限(质量过滤):0.02 在 prior 池 0513 全量保留 ~41%,
-     * 量大有意义;priorScene/posterior 池基数小且分布偏低,仍保持 >0(在 groupAndTopK 内兜底)。 */
-    private static final double PRIOR_MIN_ROV = 0.02;
+    /** prior/posterior 池视频近 7 日 rov 下限(质量过滤):0.02 在 prior 池 0513 全量保留 ~41%,
+     * cdjh 优质相似 0514 验证保留 ~54%,量大有意义;
+     * priorScene 池基数小(单 channel 几十~百条),仍保持 >0(在 groupAndTopK 内兜底)。 */
+    private static final double DEMAND_MIN_ROV = 0.02;
     /** type → channel_name 映射(强过滤):同 crowd_segment 跨渠道客户(如 gzyhc/wxm)按入口平台切数据源 */
     /** type → channel_name 映射(强过滤):同 crowd_segment 跨渠道客户(如 gzyhc/wxm)按入口平台切数据源 */
     private static final String CHANNEL_NAME_GZH = "公众号合作-即转-稳定";
     private static final String CHANNEL_NAME_GZH = "公众号合作-即转-稳定";
     private static final String CHANNEL_NAME_QW  = "群/企微合作-稳定";
     private static final String CHANNEL_NAME_QW  = "群/企微合作-稳定";
     private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
     private static final double PRIOR_GROUP_KEEP_RATIO = 0.5;
-    private static final String POSTERIOR_DRIVE_DIMENSION_TIME = "昨日";
     /** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
     /** posterior 按 demand_content_id 分组后保留 total_rov 排名前 50% 的需求组,
      * 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
      * 砍掉群体表现弱的需求,避免低 total_rov 的 demand 带回来的相似变体稀释结果。 */
     private static final double POSTERIOR_GROUP_KEEP_RATIO = 0.5;
     private static final double POSTERIOR_GROUP_KEEP_RATIO = 0.5;
@@ -938,9 +938,9 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
                     dt, channelName, null, DEMAND_STRATEGY_PRIOR, PRIOR_PREMIUM_DIMENSION, null, null, null, null, category, fetchLimit, false);
                     dt, channelName, null, DEMAND_STRATEGY_PRIOR, PRIOR_PREMIUM_DIMENSION, null, null, null, null, category, fetchLimit, false);
         }
         }
 
 
-        // prior 池近 7 日 rov 下限,过滤掉低质量近期表现的视频(0513 验证 ≥0.02 保留 ~41%)
+        // 近 7 日 rov 下限,过滤掉低质量近期表现的视频(0513 验证 ≥0.02 保留 ~41%)
         rows = rows.stream()
         rows = rows.stream()
-                .filter(r -> r.getRov() != null && r.getRov() >= PRIOR_MIN_ROV)
+                .filter(r -> r.getRov() != null && r.getRov() >= DEMAND_MIN_ROV)
                 .collect(Collectors.toList());
                 .collect(Collectors.toList());
 
 
         Function<ContentPlatformDemandVideo, String> keyFn = r ->
         Function<ContentPlatformDemandVideo, String> keyFn = r ->
@@ -1005,23 +1005,26 @@ public class ContentPlatformPlanServiceImpl implements ContentPlatformPlanServic
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
         int fetchLimit = Math.max(limit * 3, DEMAND_CANDIDATE_LIMIT);
 
 
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
         String category = StringUtils.hasText(param.getCategory()) ? param.getCategory() : null;
-        // 公众号粒度(channel_level3 有值)时放开 drive_dimension_time:单公众号数据更稀疏,"昨日"窗口经常拿不到几条,
-        // 放宽为不限制能把"最近 15 日"那一档相似召回也带进来。渠道粒度兜底仍按"昨日"。
-        String stageDriveDimensionTime = (ghName != null) ? null : POSTERIOR_DRIVE_DIMENSION_TIME;
+        // 优质相似池:drive_dimension_time 一律不限制(含主查与退化路径),避免仅「昨日」窗口召回过少。
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
         List<ContentPlatformDemandVideo> rows = demandVideoMapperExt.selectForRecommend(
-                dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, stageDriveDimensionTime, category, fetchLimit, true);
+                dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, ghName, null, category, fetchLimit, true);
 
 
-        // 退化:该 ghName 无数据 → 退回渠道粒度(drive_dimension_time 仍严格为"昨日")
+        // 退化:该 ghName 无数据 → 退回渠道粒度
         if (ghName != null && rows.isEmpty()) {
         if (ghName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
+                    dt, channelName, crowdSegment, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, fetchLimit, true);
         }
         }
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
         // 跨渠道退化:channel_name 命中但 crowd_segment 在对侧 0 行 → 去 crowd_segment 拉通用数据
         if (channelName != null && rows.isEmpty()) {
         if (channelName != null && rows.isEmpty()) {
             rows = demandVideoMapperExt.selectForRecommend(
             rows = demandVideoMapperExt.selectForRecommend(
-                    dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, POSTERIOR_DRIVE_DIMENSION_TIME, category, fetchLimit, true);
+                    dt, channelName, null, DEMAND_STRATEGY_POSTERIOR, null, null, null, null, null, category, fetchLimit, true);
         }
         }
 
 
+        // 近 7 日 rov 下限,与 prior 池一致(cdjh 0514 验证 ≥0.02 保留 ~54%)
+        rows = rows.stream()
+                .filter(r -> r.getRov() != null && r.getRov() >= DEMAND_MIN_ROV)
+                .collect(Collectors.toList());
+
         Function<ContentPlatformDemandVideo, String> keyFn = r ->
         Function<ContentPlatformDemandVideo, String> keyFn = r ->
                 r.getDemandContentId() == null ? "" : r.getDemandContentId();
                 r.getDemandContentId() == null ? "" : r.getDemandContentId();
 
 

+ 11 - 9
docs/recommend-ordering.md

@@ -35,12 +35,13 @@ source 空(默认)  ──────►  四路随机穿插 (getInterleave
 | `DEMAND_STRATEGY_PRIOR_SCENE` | `"人群需求-场景"` | 场景池过滤值(旧名「先验需求-场景」) |
 | `DEMAND_STRATEGY_PRIOR_SCENE` | `"人群需求-场景"` | 场景池过滤值(旧名「先验需求-场景」) |
 | `DEMAND_STRATEGY_POSTERIOR` | `"优质相似"` | 优质相似池过滤值(posterior,旧名「后验需求」) |
 | `DEMAND_STRATEGY_POSTERIOR` | `"优质相似"` | 优质相似池过滤值(posterior,旧名「后验需求」) |
 | `PRIOR_PREMIUM_DIMENSION` | `"传播的头部"` | prior 池 dimension 强过滤 |
 | `PRIOR_PREMIUM_DIMENSION` | `"传播的头部"` | prior 池 dimension 强过滤 |
-| `PRIOR_MIN_ROV` | `0.02` | prior 池近 7 日 rov 下限(只对 prior 池;priorScene/posterior 仍 >0) |
+| `DEMAND_MIN_ROV` | `0.02` | prior / posterior 池近 7 日 rov 下限(priorScene 池基数小,仍 >0) |
 | `CHANNEL_NAME_GZH` | `"公众号合作-即转-稳定"` | 公众号入口对应 `channel_name` 强过滤值 |
 | `CHANNEL_NAME_GZH` | `"公众号合作-即转-稳定"` | 公众号入口对应 `channel_name` 强过滤值 |
 | `CHANNEL_NAME_QW`  | `"群/企微合作-稳定"`     | 企微入口对应 `channel_name` 强过滤值 |
 | `CHANNEL_NAME_QW`  | `"群/企微合作-稳定"`     | 企微入口对应 `channel_name` 强过滤值 |
 | `PRIOR_GROUP_KEEP_RATIO` | `0.5` | prior 池"特征组"按 total_rov 分位保留比例 |
 | `PRIOR_GROUP_KEEP_RATIO` | `0.5` | prior 池"特征组"按 total_rov 分位保留比例 |
 | `POSTERIOR_GROUP_KEEP_RATIO` | `0.5` | posterior 池 demand_content_id 组按 total_rov 中位数及以上保留 |
 | `POSTERIOR_GROUP_KEEP_RATIO` | `0.5` | posterior 池 demand_content_id 组按 total_rov 中位数及以上保留 |
-| `POSTERIOR_DRIVE_DIMENSION_TIME` | `"昨日"` | posterior 池 `drive_dimension_time` 强制值(仅渠道粒度兜底使用;公众号粒度放开) |
+
+> 优质相似池 SQL **不**加 `drive_dimension_time` 条件(主查与 ghName/跨渠道退化路径一致),可包含「昨日」以外驱动时间档位的数据。
 
 
 公共强过滤(所有 demand 池 SQL):`dt = max(dt)` AND `status = 1` AND `crowd_segment = user.channel` AND `channel_name = resolveChannelName(param)`(可空)。
 公共强过滤(所有 demand 池 SQL):`dt = max(dt)` AND `status = 1` AND `crowd_segment = user.channel` AND `channel_name = resolveChannelName(param)`(可空)。
 
 
@@ -138,17 +139,18 @@ ORDER BY total_rov DESC, score DESC LIMIT 30000
 ```sql
 ```sql
 SELECT ... WHERE ... AND channel_name=:resolvedChannelName(可空)
 SELECT ... WHERE ... AND channel_name=:resolvedChannelName(可空)
   AND demand_strategy='优质相似'
   AND demand_strategy='优质相似'
-  AND drive_dimension_time=:stageDriveDimensionTime  -- 见下
+  -- 不加 drive_dimension_time 条件
   AND (title IS NULL OR demand_content_title IS NULL OR title <> demand_content_title)
   AND (title IS NULL OR demand_content_title IS NULL OR title <> demand_content_title)
 ORDER BY total_rov DESC, score DESC LIMIT 30000
 ORDER BY total_rov DESC, score DESC LIMIT 30000
 ```
 ```
 
 
-**`drive_dimension_time` 公众号粒度放开**:
-- `ghName` 非空(公众号粒度,channel_level3 命中)→ `stageDriveDimensionTime = null`,不限驱动时间维度(把"最近 15 日"也带进来,单公众号"昨日"窗口经常拿不到几条)
-- `ghName` 为空(渠道粒度)→ 仍强制 `drive_dimension_time='昨日'`
-- 两条退化(去 `ghName` / 去 `crowd_segment`)路径都用 `'昨日'`,只在主查询放宽
+**`drive_dimension_time`**: 优质相似池**一律不限制**(主查与退化路径均不传该维度),与公众号/渠道粒度无关。
+
+退化阶梯:主查询空且 `ghName` 非空 → 去 `ghName` 重查;仍空且 `channel_name` 非空 → 再去 `crowd_segment` 重查(跨渠道兜底)。`channel_name` 强过滤始终保留。
 
 
-退化阶梯:主查询空且 `ghName` 非空 → 去 `ghName` 重查(drive_dimension_time 严回"昨日");仍空且 `channel_name` 非空 → 再去 `crowd_segment` 重查(跨渠道兜底)。`channel_name` 强过滤始终保留。
+**[新] 近 7 日 rov 下限(`DEMAND_MIN_ROV=0.02`)**:
+- 与 prior 池一致,过滤掉视频 rov < 0.02 的低质量近期表现
+- cdjh 优质相似 0514 全量验证保留 ~54%,priorScene 池基数小不加该过滤
 
 
 **[新] 需求组分位裁剪 (`retainTopGroupsByTotalRov`,`keepRatio=POSTERIOR_GROUP_KEEP_RATIO=0.5`)**:
 **[新] 需求组分位裁剪 (`retainTopGroupsByTotalRov`,`keepRatio=POSTERIOR_GROUP_KEEP_RATIO=0.5`)**:
 - 按 `demand_content_id` 分组,取每组 `max(total_rov)`(需求组的群体强度)
 - 按 `demand_content_id` 分组,取每组 `max(total_rov)`(需求组的群体强度)
@@ -271,7 +273,7 @@ list = fetchPosteriorCandidates(...)   // 顺序 = total_rov DESC, score DESC (
    ┌───────────────────────┬──┴──┬─────────────────────────────┐
    ┌───────────────────────┬──┴──┬─────────────────────────────┐
    ▼                       ▼     ▼                             ▼
    ▼                       ▼     ▼                             ▼
 priorScene(10000)    prior(10000)  posterior(10000)         hot(10000)
 priorScene(10000)    prior(10000)  posterior(10000)         hot(10000)
-  视频维度 rov DESC   传播头部       优质相似 + 驱动时间(ghName 时放开) SQL 默认
+  视频维度 rov DESC   传播头部       优质相似(不按 drive_dimension_time 过滤) SQL 默认
   (代表需求 total_rov 选最大)        组 total_rov 中位数及以上            (sort 决定)
   (代表需求 total_rov 选最大)        组 total_rov 中位数及以上            (sort 决定)
                      组(point_type, standard_element) top3
                      组(point_type, standard_element) top3
                      组(demand_content_id) top3
                      组(demand_content_id) top3