|
|
@@ -9,10 +9,10 @@ import com.tzld.videoVector.api.VideoApiService;
|
|
|
import com.tzld.videoVector.common.constant.VectorConstants;
|
|
|
import com.tzld.videoVector.common.enums.Modality;
|
|
|
import com.tzld.videoVector.dao.mapper.pgVector.DeconstructVectorConfigMapper;
|
|
|
+import com.tzld.videoVector.dao.mapper.pgVector.ext.AdsMaterialTouliuAllChannelMapperExt;
|
|
|
import com.tzld.videoVector.dao.mapper.pgVector.ext.ArticleDeconstructResultMapperExt;
|
|
|
import com.tzld.videoVector.dao.mapper.pgVector.ext.ArticleQualityMapperExt;
|
|
|
import com.tzld.videoVector.dao.mapper.pgVector.ext.MaterialDeconstructResultMapperExt;
|
|
|
-import com.tzld.videoVector.dao.mapper.pgVector.ext.MaterialQualityMapperExt;
|
|
|
import com.tzld.videoVector.model.entity.ArticleMatch;
|
|
|
import com.tzld.videoVector.model.entity.MaterialMatch;
|
|
|
import com.tzld.videoVector.model.entity.VideoDetail;
|
|
|
@@ -27,8 +27,8 @@ import com.tzld.videoVector.model.po.pgVector.ArticleDeconstructResult;
|
|
|
import com.tzld.videoVector.model.po.pgVector.ArticleQuality;
|
|
|
import com.tzld.videoVector.model.po.pgVector.DeconstructVectorConfig;
|
|
|
import com.tzld.videoVector.model.po.pgVector.DeconstructVectorConfigExample;
|
|
|
+import com.tzld.videoVector.model.po.pgVector.AdsMaterialTouliuAllChannel;
|
|
|
import com.tzld.videoVector.model.po.pgVector.MaterialDeconstructResult;
|
|
|
-import com.tzld.videoVector.model.po.pgVector.MaterialQuality;
|
|
|
import com.tzld.videoVector.model.vo.VideoMatchResult;
|
|
|
import com.tzld.videoVector.model.vo.recall.AIUnderstandingVO;
|
|
|
import com.tzld.videoVector.model.vo.recall.ArticleBasicVO;
|
|
|
@@ -49,6 +49,7 @@ import com.tzld.videoVector.service.MaterialVectorStoreService;
|
|
|
import com.tzld.videoVector.service.VectorStoreService;
|
|
|
import com.tzld.videoVector.service.VideoSearchService;
|
|
|
import com.tzld.videoVector.service.recall.VectorRecallTestService;
|
|
|
+import com.tzld.videoVector.util.MaterialQualityCalculator;
|
|
|
import com.tzld.videoVector.util.Md5Util;
|
|
|
import com.tzld.videoVector.util.RedisUtils;
|
|
|
import com.tzld.videoVector.model.po.pgVector.ArticleVector;
|
|
|
@@ -63,6 +64,8 @@ import org.springframework.util.StringUtils;
|
|
|
|
|
|
import javax.annotation.PreDestroy;
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
@@ -106,7 +109,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
private MaterialDeconstructResultMapperExt materialDeconstructResultMapperExt;
|
|
|
|
|
|
@Autowired
|
|
|
- private MaterialQualityMapperExt materialQualityMapperExt;
|
|
|
+ private AdsMaterialTouliuAllChannelMapperExt adsMaterialTouliuAllChannelMapperExt;
|
|
|
|
|
|
@Autowired
|
|
|
private ArticleVectorStoreService articleVectorStoreService;
|
|
|
@@ -257,10 +260,11 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
}, RECALL_EXECUTOR)
|
|
|
: CompletableFuture.completedFuture(Collections.emptyList());
|
|
|
|
|
|
+ int materialDays = param.getDays() != null ? param.getDays() : metricsDays;
|
|
|
CompletableFuture<List<VideoMatchEnrichedVO>> materialFuture = needMaterial
|
|
|
? CompletableFuture.supplyAsync(
|
|
|
() -> recallMaterialItems(param.getQueryText(), finalConfigCode, finalMaterialRecallK,
|
|
|
- toSourceType(param.getSourceLabels())),
|
|
|
+ toSourceType(param.getSourceLabels()), materialDays),
|
|
|
RECALL_EXECUTOR)
|
|
|
: CompletableFuture.completedFuture(Collections.emptyList());
|
|
|
|
|
|
@@ -429,25 +433,25 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
// 视频去重
|
|
|
List<VideoMatchResult> dedupedVideo = deduplicateRaw(allRawVideo,
|
|
|
VideoMatchResult::getVideoId, m -> m.getScore() != null ? m.getScore() : 0.0);
|
|
|
- // 素材去重 + 批量查 quality 做轻量预打分(不等 full enrich)
|
|
|
+ // 素材去重 + 批量查 touliu 做轻量预打分(不等 full enrich)
|
|
|
List<MaterialMatch> dedupedMaterial = deduplicateRaw(allRawMaterial,
|
|
|
MaterialMatch::getMaterialId, MaterialMatch::getScore);
|
|
|
List<String> matIds = dedupedMaterial.stream()
|
|
|
.map(MaterialMatch::getMaterialId).distinct().limit(enrichK * 2)
|
|
|
.collect(Collectors.toList());
|
|
|
- Map<String, MaterialQuality> qualitySnapshot = matIds.isEmpty()
|
|
|
- ? Collections.emptyMap() : loadMaterialQualityRows(matIds);
|
|
|
+ int preDays = param.getDays() != null ? param.getDays() : metricsDays;
|
|
|
+ Map<String, AdsMaterialTouliuAllChannel> statsSnapshot = matIds.isEmpty()
|
|
|
+ ? Collections.emptyMap() : loadMaterialTouliuStats(matIds, preDays);
|
|
|
// 文章去重
|
|
|
List<ArticleMatch> dedupedArticle = deduplicateRaw(allRawArticle,
|
|
|
ArticleMatch::getArticleId, ArticleMatch::getScore);
|
|
|
|
|
|
double preAlpha = RankingParams.defaults().getAlpha(); // 0.6
|
|
|
|
|
|
- // 素材预打分:sim + quality 轻量复合,有质量数据的获得加成
|
|
|
+ // 素材预打分:sim + quality 轻量复合
|
|
|
List<MaterialMatch> topMaterial = dedupedMaterial.stream()
|
|
|
.sorted(Comparator.comparingDouble((MaterialMatch m) -> {
|
|
|
- MaterialQuality mq = qualitySnapshot.get(m.getMaterialId());
|
|
|
- double qs = (mq != null && mq.getQualityScore() != null) ? mq.getQualityScore() : 0;
|
|
|
+ double qs = computeSimpleQualityScore(statsSnapshot.get(m.getMaterialId()));
|
|
|
return -(preAlpha * m.getScore() + (1 - preAlpha) * qs);
|
|
|
}))
|
|
|
.limit(enrichK).collect(Collectors.toList());
|
|
|
@@ -465,10 +469,37 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
List<VideoMatchEnrichedVO> videoItems = enrichVideoMatches(topVideo, configCodes.get(0), param.getDays());
|
|
|
for (int i = 0; i < videoItems.size() && i < topVideo.size(); i++) {
|
|
|
String cc = topVideo.get(i).getConfigCode();
|
|
|
- if (cc != null) videoItems.get(i).setConfigCode(cc);
|
|
|
+ if (cc != null) {
|
|
|
+ videoItems.get(i).setConfigCode(cc);
|
|
|
+ if (videoItems.get(i).getSignals() != null
|
|
|
+ && videoItems.get(i).getSignals().getProvenance() != null) {
|
|
|
+ videoItems.get(i).getSignals().getProvenance().setConfigCode(cc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ int matDays = param.getDays() != null ? param.getDays() : metricsDays;
|
|
|
+ List<VideoMatchEnrichedVO> materialItems = enrichMaterialMatches(topMaterial, configCodes.get(0), matDays);
|
|
|
+ for (int i = 0; i < materialItems.size() && i < topMaterial.size(); i++) {
|
|
|
+ String cc = topMaterial.get(i).getConfigCode();
|
|
|
+ if (cc != null) {
|
|
|
+ materialItems.get(i).setConfigCode(cc);
|
|
|
+ if (materialItems.get(i).getSignals() != null
|
|
|
+ && materialItems.get(i).getSignals().getProvenance() != null) {
|
|
|
+ materialItems.get(i).getSignals().getProvenance().setConfigCode(cc);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- List<VideoMatchEnrichedVO> materialItems = enrichMaterialMatches(topMaterial, configCodes.get(0));
|
|
|
List<VideoMatchEnrichedVO> articleItems = enrichArticleMatches(topArticle, configCodes.get(0));
|
|
|
+ for (int i = 0; i < articleItems.size() && i < topArticle.size(); i++) {
|
|
|
+ String cc = topArticle.get(i).getConfigCode();
|
|
|
+ if (cc != null) {
|
|
|
+ articleItems.get(i).setConfigCode(cc);
|
|
|
+ if (articleItems.get(i).getSignals() != null
|
|
|
+ && articleItems.get(i).getSignals().getProvenance() != null) {
|
|
|
+ articleItems.get(i).getSignals().getProvenance().setConfigCode(cc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
log.info("batchByText 阶段二 enrich 完成(含预打分): video={}/{}, material={}/{}, article={}/{}",
|
|
|
videoItems.size(), dedupedVideo.size(),
|
|
|
@@ -651,7 +682,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
* 素材文本召回:material_vectors → material_deconstruct_result
|
|
|
*/
|
|
|
private List<VideoMatchEnrichedVO> recallMaterialItems(String queryText, String configCode,
|
|
|
- int topN, Short sourceType) {
|
|
|
+ int topN, Short sourceType, int days) {
|
|
|
try {
|
|
|
int candidate = Math.max(topN * VectorConstants.MULTI_POINT_RECALL_CANDIDATE_FACTOR,
|
|
|
VectorConstants.MULTI_POINT_RECALL_MIN_CANDIDATES);
|
|
|
@@ -677,7 +708,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
}
|
|
|
log.info("素材召回(rawVector) 去重后({}条): {}, configCode={}",
|
|
|
matches.size(), matchSample, configCode);
|
|
|
- return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode), topN);
|
|
|
+ return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode, days), topN);
|
|
|
}
|
|
|
log.info("素材召回(rawVector) 无结果, configCode={}", configCode);
|
|
|
return Collections.emptyList();
|
|
|
@@ -700,7 +731,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
}
|
|
|
log.info("素材召回(parsed vector缓存) 去重后({}条): {}, configCode={}",
|
|
|
matches.size(), matchSample, configCode);
|
|
|
- return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode), topN);
|
|
|
+ return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode, days), topN);
|
|
|
}
|
|
|
log.info("素材召回(parsed vector缓存) 无结果, configCode={}", configCode);
|
|
|
return Collections.emptyList();
|
|
|
@@ -727,7 +758,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
matchSample.add(m.getMaterialId() + ":" + String.format("%.4f", m.getScore()));
|
|
|
}
|
|
|
log.info("素材召回(embedding API) 去重后({}条): {}, configCode={}", matches.size(), matchSample, configCode);
|
|
|
- return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode), topN);
|
|
|
+ return limitEnrichedItemsByScore(enrichMaterialMatches(matches, configCode, days), topN);
|
|
|
} catch (Exception e) {
|
|
|
log.error("素材召回 material_vectors 异常: {}", e.getMessage(), e);
|
|
|
return Collections.emptyList();
|
|
|
@@ -901,7 +932,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
* - materialDetail.deconstruct:解析 dataContent 得到 topic + 灵感点/关键点/目的点
|
|
|
* - materialDetail.source:source_type → 中文标签
|
|
|
*/
|
|
|
- private List<VideoMatchEnrichedVO> enrichMaterialMatches(List<MaterialMatch> matches, String requestConfigCode) {
|
|
|
+ private List<VideoMatchEnrichedVO> enrichMaterialMatches(List<MaterialMatch> matches, String requestConfigCode, int days) {
|
|
|
if (CollectionUtils.isEmpty(matches)) {
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
@@ -910,7 +941,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
.filter(java.util.Objects::nonNull)
|
|
|
.collect(Collectors.toList());
|
|
|
Map<String, MaterialDeconstructResult> rowByMaterialId = loadMaterialDeconstructRows(materialIds);
|
|
|
- Map<String, MaterialQuality> qualityByMaterialId = loadMaterialQualityRows(materialIds);
|
|
|
+ Map<String, AdsMaterialTouliuAllChannel> statsByMaterialId = loadMaterialTouliuStats(materialIds, days);
|
|
|
|
|
|
List<VideoMatchEnrichedVO> items = new ArrayList<>(matches.size());
|
|
|
for (MaterialMatch m : matches) {
|
|
|
@@ -941,9 +972,9 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
fillMaterialDetailImageCount(detail, vo.getImageList());
|
|
|
|
|
|
// 填充投放质量数据
|
|
|
- MaterialQuality mq = qualityByMaterialId.get(m.getMaterialId());
|
|
|
- if (mq != null) {
|
|
|
- detail.setQuality(buildQualityMap(mq));
|
|
|
+ AdsMaterialTouliuAllChannel stats = statsByMaterialId.get(m.getMaterialId());
|
|
|
+ if (stats != null) {
|
|
|
+ detail.setQuality(buildQualityMap(stats, days));
|
|
|
}
|
|
|
|
|
|
vo.setMaterialDetail(detail);
|
|
|
@@ -1294,75 +1325,71 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- private Map<String, Object> buildQualityMap(MaterialQuality mq) {
|
|
|
+ private Map<String, Object> buildQualityMap(AdsMaterialTouliuAllChannel s, int days) {
|
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
|
- map.put("dt", mq.getDt());
|
|
|
- map.put("qualityScore", mq.getQualityScore());
|
|
|
- map.put("confidence", mq.getConfidence());
|
|
|
- map.put("conversionEfficiencyScore", mq.getConversionEfficiencyScore());
|
|
|
- map.put("revenueScore", mq.getRevenueScore());
|
|
|
- map.put("viralScore", mq.getViralScore());
|
|
|
- map.put("engagementScore", mq.getEngagementScore());
|
|
|
- map.put("cost7d", mq.getCost7d());
|
|
|
- map.put("targetConversion7d", mq.getTargetConversion7d());
|
|
|
- map.put("totalConversion7d", mq.getTotalConversion7d());
|
|
|
- map.put("revenue7d", mq.getRevenue7d());
|
|
|
- map.put("t0ViralCount7d", mq.getT0ViralCount7d());
|
|
|
- map.put("t0ViralRate7d", mq.getT0ViralRate7d());
|
|
|
- map.put("miniProgramOpenRate7d", mq.getMiniProgramOpenRate7d());
|
|
|
- map.put("firstUv7d", mq.getFirstUv7d());
|
|
|
- map.put("shareCount7d", mq.getShareCount7d());
|
|
|
- map.put("cost30d", mq.getCost30d());
|
|
|
- map.put("targetConversion30d", mq.getTargetConversion30d());
|
|
|
- // 派生指标
|
|
|
- Long firstUv = mq.getFirstUv7d();
|
|
|
- Long totalConv = mq.getTotalConversion7d();
|
|
|
- Long viralCount = mq.getT0ViralCount7d();
|
|
|
- Double rev = mq.getRevenue7d();
|
|
|
-
|
|
|
- // 消耗优先7天,不足时用30天兜底
|
|
|
- Double cost = mq.getCost7d();
|
|
|
- boolean use30d = cost == null || cost < 50;
|
|
|
- if (use30d && mq.getCost30d() != null && mq.getCost30d() > 0) {
|
|
|
- cost = mq.getCost30d();
|
|
|
- }
|
|
|
- map.put("use30d", use30d);
|
|
|
- map.put("effectiveCost", cost); // 实际用于计算的消耗(7d 不足时兜底为 30d)
|
|
|
-
|
|
|
- // 打开率(CTR) = 首层uv / 总转化量
|
|
|
- if (firstUv != null && firstUv > 0 && totalConv != null && totalConv > 0) {
|
|
|
- map.put("ctr7d", Math.round((double) firstUv / totalConv * 10000.0) / 10000.0);
|
|
|
- }
|
|
|
- // 裂变率 = t0裂变数 / 首层uv
|
|
|
- if (viralCount != null && viralCount > 0 && firstUv != null && firstUv > 0) {
|
|
|
- map.put("viralRate7d", Math.round((double) viralCount / firstUv * 10000.0) / 10000.0);
|
|
|
- }
|
|
|
- // ROI = 收入 / effectiveCost
|
|
|
- if (cost != null && cost > 0 && rev != null && rev > 0) {
|
|
|
- map.put("roi7d", Math.round(rev / cost * 10000.0) / 10000.0);
|
|
|
- }
|
|
|
- map.put("adOptimizationGoal", mq.getAdOptimizationGoal());
|
|
|
- map.put("packageName", mq.getPackageName());
|
|
|
- map.put("adStatus", mq.getAdStatus());
|
|
|
- map.put("creativeStatus", mq.getCreativeStatus());
|
|
|
+ map.put("dt", String.valueOf(days));
|
|
|
+ map.put("impressions", s.getImpressions());
|
|
|
+ map.put("clicks", s.getClicks());
|
|
|
+ map.put("conversions", s.getConversions());
|
|
|
+ map.put("cost", s.getCost());
|
|
|
+ map.put("income", s.getIncome());
|
|
|
+ map.put("firstUv", s.getFirstUv());
|
|
|
+ map.put("fission0Uv", s.getFission0Uv());
|
|
|
+
|
|
|
+ // 效率指标
|
|
|
+ Double ctr = MaterialQualityCalculator.divide(s.getClicks(), s.getImpressions());
|
|
|
+ Double cvr = MaterialQualityCalculator.divide(s.getConversions(), s.getImpressions());
|
|
|
+ Double roi = MaterialQualityCalculator.divide(s.getIncome(), s.getCost());
|
|
|
+ Double openRate = MaterialQualityCalculator.divide(s.getFirstUv(), s.getConversions());
|
|
|
+ Double fissionRate = MaterialQualityCalculator.divide(s.getFission0Uv(), s.getFirstUv());
|
|
|
+ if (ctr != null) { map.put("ctr", MaterialQualityCalculator.round4(ctr)); map.put("ctrScore", MaterialQualityCalculator.round4(ctr)); }
|
|
|
+ if (cvr != null) { map.put("cvr", MaterialQualityCalculator.round4(cvr)); map.put("cvrScore", MaterialQualityCalculator.round4(cvr)); }
|
|
|
+ if (roi != null) { map.put("roi", MaterialQualityCalculator.round4(roi)); map.put("roiScore", MaterialQualityCalculator.round4(roi)); }
|
|
|
+ if (openRate != null) { map.put("openRate", MaterialQualityCalculator.round4(openRate)); map.put("openRateScore", MaterialQualityCalculator.round4(openRate)); }
|
|
|
+ if (fissionRate != null) { map.put("fissionRate", MaterialQualityCalculator.round4(fissionRate)); map.put("fissionRateScore", MaterialQualityCalculator.round4(fissionRate)); }
|
|
|
+
|
|
|
+ // 综合质量分(等权加权,测试路径无批内百分位排名,用原始比率近似)
|
|
|
+ double qs = computeSimpleQualityScore(s);
|
|
|
+ map.put("qualityScore", MaterialQualityCalculator.round4(qs));
|
|
|
+
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
- private Map<String, MaterialQuality> loadMaterialQualityRows(List<String> materialIds) {
|
|
|
+ /** 简单质量分:加权求和,与 MaterialSearchServiceImpl 权重默认值保持一致 */
|
|
|
+ private double computeSimpleQualityScore(AdsMaterialTouliuAllChannel s) {
|
|
|
+ if (s == null) return 0;
|
|
|
+ double wCtr = 0.2, wCvr = 0.2, wRoi = 0.2, wOpenRate = 0.2, wFissionRate = 0.2;
|
|
|
+ Double ctr = MaterialQualityCalculator.divide(s.getClicks(), s.getImpressions());
|
|
|
+ Double cvr = MaterialQualityCalculator.divide(s.getConversions(), s.getImpressions());
|
|
|
+ Double roi = MaterialQualityCalculator.divide(s.getIncome(), s.getCost());
|
|
|
+ Double openRate = MaterialQualityCalculator.divide(s.getFirstUv(), s.getConversions());
|
|
|
+ Double fissionRate = MaterialQualityCalculator.divide(s.getFission0Uv(), s.getFirstUv());
|
|
|
+ return (ctr != null ? wCtr * ctr : 0)
|
|
|
+ + (cvr != null ? wCvr * cvr : 0)
|
|
|
+ + (roi != null ? wRoi * roi : 0)
|
|
|
+ + (openRate != null ? wOpenRate * openRate : 0)
|
|
|
+ + (fissionRate != null ? wFissionRate * fissionRate : 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, AdsMaterialTouliuAllChannel> loadMaterialTouliuStats(
|
|
|
+ List<String> materialIds, int days) {
|
|
|
if (CollectionUtils.isEmpty(materialIds)) {
|
|
|
return Collections.emptyMap();
|
|
|
}
|
|
|
- Map<String, MaterialQuality> result = new HashMap<>();
|
|
|
+ Map<String, AdsMaterialTouliuAllChannel> result = new HashMap<>();
|
|
|
try {
|
|
|
- List<MaterialQuality> rows = materialQualityMapperExt.selectByMaterialIds(materialIds);
|
|
|
+ String dtThreshold = LocalDate.now().minusDays(days)
|
|
|
+ .format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
|
|
+ List<AdsMaterialTouliuAllChannel> rows = adsMaterialTouliuAllChannelMapperExt
|
|
|
+ .aggregateByMaterialIds(materialIds, dtThreshold);
|
|
|
if (CollectionUtils.isEmpty(rows)) return result;
|
|
|
- for (MaterialQuality row : rows) {
|
|
|
+ for (AdsMaterialTouliuAllChannel row : rows) {
|
|
|
if (row != null && row.getMaterialId() != null) {
|
|
|
result.putIfAbsent(row.getMaterialId(), row);
|
|
|
}
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- log.error("批量加载 material_quality 失败: {}", e.getMessage(), e);
|
|
|
+ log.error("批量加载 ads_material_touliu_all_channel 失败: {}", e.getMessage(), e);
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
@@ -1813,9 +1840,9 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
? vo.getMaterialDetail().getQuality() : null;
|
|
|
if (qualityMap != null && !qualityMap.isEmpty()) {
|
|
|
qs.setHasData(true);
|
|
|
- qs.setCtr(toDoubleOrNull(qualityMap.get("conversionEfficiencyScore")));
|
|
|
- qs.setViral(toDoubleOrNull(qualityMap.get("viralScore")));
|
|
|
- qs.setRoi(toDoubleOrNull(qualityMap.get("revenueScore")));
|
|
|
+ qs.setCtr(toDoubleOrNull(qualityMap.get("ctr")));
|
|
|
+ qs.setViral(toDoubleOrNull(qualityMap.get("fissionRate")));
|
|
|
+ qs.setRoi(toDoubleOrNull(qualityMap.get("roi")));
|
|
|
} else {
|
|
|
qs.setHasData(false);
|
|
|
}
|
|
|
@@ -1973,7 +2000,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
.collect(Collectors.toList());
|
|
|
List<MaterialMatch> deduped = deduplicateMaterialMatches(matches, tn);
|
|
|
if (!deduped.isEmpty()) {
|
|
|
- allResults.addAll(enrichMaterialMatches(deduped, cc));
|
|
|
+ allResults.addAll(enrichMaterialMatches(deduped, cc, metricsDays));
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("matchByMaterialId 素材搜索失败 configCode={}: {}", cc, e.getMessage(), e);
|
|
|
@@ -2363,7 +2390,7 @@ public class VectorRecallTestServiceImpl implements VectorRecallTestService {
|
|
|
List<MaterialMatch> matches = materialVectorStoreService.searchTopNByRawVector(cc, rawEmbedding, ctn);
|
|
|
List<MaterialMatch> deduped = deduplicateMaterialMatches(matches, tn);
|
|
|
if (!deduped.isEmpty()) {
|
|
|
- allResults.addAll(enrichMaterialMatches(deduped, cc));
|
|
|
+ allResults.addAll(enrichMaterialMatches(deduped, cc, metricsDays));
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("matchByArticleId 素材搜索失败 configCode={}: {}", cc, e.getMessage(), e);
|