|
@@ -4,13 +4,15 @@
|
|
|
流程:
|
|
流程:
|
|
|
1. 比对当天 ODPS / MySQL 行数,相同则跳过写入
|
|
1. 比对当天 ODPS / MySQL 行数,相同则跳过写入
|
|
|
2. 有差异时拉取 ODPS,按 (strategy, demand_id) 只插入缺失、删除多余,并回填已有行 video_list
|
|
2. 有差异时拉取 ODPS,按 (strategy, demand_id) 只插入缺失、删除多余,并回填已有行 video_list
|
|
|
-3. video_list 每条最多保留前 100 个 video_id,video_count 与之保持一致
|
|
|
|
|
|
|
+3. video_list 每条最多保留前 10 个 video_id,video_count 与之保持一致
|
|
|
4. 拉取近 7 日真实 ROV/VOV,按特征值匹配回填 real_rov_7d / real_vov_7d
|
|
4. 拉取近 7 日真实 ROV/VOV,按特征值匹配回填 real_rov_7d / real_vov_7d
|
|
|
5. 查询当天全部 demand_name,按空格分词写入 set
|
|
5. 查询当天全部 demand_name,按空格分词写入 set
|
|
|
6. 过滤 demand_belong_category 中已存在的词
|
|
6. 过滤 demand_belong_category 中已存在的词
|
|
|
7. 剩余词按 100 词一批调用 demand_belong_category_agent
|
|
7. 剩余词按 100 词一批调用 demand_belong_category_agent
|
|
|
8. 遍历 demand_belong_category 全部词,按策略与真实 ROV/VOV 写入 demand_popularity_stats(avg/count)
|
|
8. 遍历 demand_belong_category 全部词,按策略与真实 ROV/VOV 写入 demand_popularity_stats(avg/count)
|
|
|
9. 基于三表计算整棵类目树节点加权平均分,写入 category_tree_weight
|
|
9. 基于三表计算整棵类目树节点加权平均分,写入 category_tree_weight
|
|
|
|
|
+10. 增量同步 multi_demand_video_detail(全表 video_list → ODPS 昨天分区最终选题)
|
|
|
|
|
+11. 补充 demand_belong_pool_rel 匹配边,并回填词级 video_list(最多 10 个)
|
|
|
"""
|
|
"""
|
|
|
from __future__ import annotations
|
|
from __future__ import annotations
|
|
|
|
|
|
|
@@ -33,6 +35,10 @@ from supply_infra.odps.client import get_odps_client
|
|
|
from supply_infra.scheduler.jobs.compute_category_tree_weight import (
|
|
from supply_infra.scheduler.jobs.compute_category_tree_weight import (
|
|
|
compute_category_tree_weight,
|
|
compute_category_tree_weight,
|
|
|
)
|
|
)
|
|
|
|
|
+from supply_infra.scheduler.jobs.sync_demand_belong_pool_rel import (
|
|
|
|
|
+ sync_demand_belong_pool_rel,
|
|
|
|
|
+)
|
|
|
|
|
+from supply_infra.scheduler.jobs.sync_multi_demand_videos import sync_multi_demand_videos
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
@@ -41,7 +47,7 @@ _STATS_UPSERT_BATCH = 200
|
|
|
_REAL_METRIC_LIMIT = 1000
|
|
_REAL_METRIC_LIMIT = 1000
|
|
|
_REAL_METRIC_LOOKBACK_DAYS = 7
|
|
_REAL_METRIC_LOOKBACK_DAYS = 7
|
|
|
_GLOBAL_FEATURE_VALUE = "全局SUM"
|
|
_GLOBAL_FEATURE_VALUE = "全局SUM"
|
|
|
-_VIDEO_LIST_LIMIT = 100
|
|
|
|
|
|
|
+_VIDEO_LIST_LIMIT = 10
|
|
|
|
|
|
|
|
# 策略名 → 统计字段前缀;去年同期阳历/阴历合并为 plat_ly_pop
|
|
# 策略名 → 统计字段前缀;去年同期阳历/阴历合并为 plat_ly_pop
|
|
|
_STRATEGY_METRIC: dict[str, str] = {
|
|
_STRATEGY_METRIC: dict[str, str] = {
|
|
@@ -221,7 +227,7 @@ def _sync_diff(partition_date: str) -> dict[str, Any]:
|
|
|
|
|
|
|
|
|
|
|
|
|
def backfill_video_list(partition_date: str) -> dict[str, Any]:
|
|
def backfill_video_list(partition_date: str) -> dict[str, Any]:
|
|
|
- """从 ODPS 回填指定分区的 video_list / video_count(每条最多前 100 个 video_id)。"""
|
|
|
|
|
|
|
+ """从 ODPS 回填指定分区的 video_list / video_count(每条最多前 10 个 video_id)。"""
|
|
|
logger.info("Backfill video_list for partition: %s", partition_date)
|
|
logger.info("Backfill video_list for partition: %s", partition_date)
|
|
|
odps = get_odps_client()
|
|
odps = get_odps_client()
|
|
|
raw_rows = odps.fetch_multi_demand_pool(partition_date)
|
|
raw_rows = odps.fetch_multi_demand_pool(partition_date)
|
|
@@ -510,17 +516,21 @@ def sync_multi_demand_pool_odps_to_mysql(partition_date: str | None = None) -> d
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
classify_stats = _classify_words(partition_date)
|
|
classify_stats = _classify_words(partition_date)
|
|
|
|
|
+ belong_pool_rel_stats = sync_demand_belong_pool_rel()
|
|
|
real_metric_stats = enrich_real_rov_vov_7d(partition_date)
|
|
real_metric_stats = enrich_real_rov_vov_7d(partition_date)
|
|
|
popularity_stats = compute_popularity_stats(partition_date)
|
|
popularity_stats = compute_popularity_stats(partition_date)
|
|
|
tree_weight_stats = compute_category_tree_weight(partition_date)
|
|
tree_weight_stats = compute_category_tree_weight(partition_date)
|
|
|
|
|
+ video_stats = sync_multi_demand_videos(limit=None)
|
|
|
|
|
|
|
|
result = {
|
|
result = {
|
|
|
"partition_date": partition_date,
|
|
"partition_date": partition_date,
|
|
|
**sync_stats,
|
|
**sync_stats,
|
|
|
"real_metrics": real_metric_stats,
|
|
"real_metrics": real_metric_stats,
|
|
|
"classify": classify_stats,
|
|
"classify": classify_stats,
|
|
|
|
|
+ "belong_pool_rel": belong_pool_rel_stats,
|
|
|
"popularity": popularity_stats,
|
|
"popularity": popularity_stats,
|
|
|
"tree_weight": tree_weight_stats,
|
|
"tree_weight": tree_weight_stats,
|
|
|
|
|
+ "videos": video_stats,
|
|
|
"synced_at": datetime.now().isoformat(),
|
|
"synced_at": datetime.now().isoformat(),
|
|
|
}
|
|
}
|
|
|
logger.info("Multi demand pool sync completed: %s", result)
|
|
logger.info("Multi demand pool sync completed: %s", result)
|