|
|
@@ -1,16 +1,21 @@
|
|
|
package com.tzld.longarticle.recommend.server.service.recommend.rank.strategy;
|
|
|
|
|
|
+import com.tzld.longarticle.recommend.server.common.enums.aigc.PublishPlanInputSourceTypesEnum;
|
|
|
import com.tzld.longarticle.recommend.server.common.enums.recommend.ScoreStrategyEnum;
|
|
|
import com.tzld.longarticle.recommend.server.model.dto.Content;
|
|
|
+import com.tzld.longarticle.recommend.server.model.entity.crawler.Article;
|
|
|
+import com.tzld.longarticle.recommend.server.repository.crawler.ArticleRepository;
|
|
|
import com.tzld.longarticle.recommend.server.service.recommend.config.AccountContentPoolConfigService;
|
|
|
import com.tzld.longarticle.recommend.server.service.recommend.config.StrategyIndexScoreWeightService;
|
|
|
import com.tzld.longarticle.recommend.server.service.recommend.rank.*;
|
|
|
-import com.tzld.longarticle.recommend.server.service.recommend.score.ScoreParam;
|
|
|
+import com.tzld.longarticle.recommend.server.service.recommend.score.AccountIndexReplacePoolConfig;
|
|
|
import com.tzld.longarticle.recommend.server.service.recommend.score.ScoreResult;
|
|
|
import com.tzld.longarticle.recommend.server.service.recommend.score.ScoreService;
|
|
|
import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.util.*;
|
|
|
@@ -23,32 +28,97 @@ public class InfiniteRankStrategy implements RankStrategy {
|
|
|
@Autowired
|
|
|
private ScoreService scoreService;
|
|
|
@Autowired
|
|
|
+ private RankService rankService;
|
|
|
+ @Autowired
|
|
|
private AccountContentPoolConfigService accountContentPoolConfigService;
|
|
|
@Autowired
|
|
|
+ private ArticleRepository articleRepository;
|
|
|
+ @Autowired
|
|
|
private StrategyIndexScoreWeightService weightService;
|
|
|
|
|
|
+ @Value("${topProducePlanId:}")
|
|
|
+ private String topProducePlanId;
|
|
|
+ @Value("${hisFissionOpenRateMissingBaseline:0.32}")
|
|
|
+ private double hisFissionOpenRateMissingBaseline;
|
|
|
+
|
|
|
public RankResult rank(RankParam param) {
|
|
|
List<Content> result = new ArrayList<>();
|
|
|
- String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
|
|
|
- ScoreParam scoreParam = RankStrategy.convertToScoreParam(param);
|
|
|
- scoreParam.setContents(scoreParam.getContents().stream().filter(
|
|
|
- c -> contentPools[2].equals(c.getContentPoolType())).collect(Collectors.toList()));
|
|
|
+
|
|
|
ScoreResult scoreResult = scoreService.score(RankStrategy.convertToScoreParam(param));
|
|
|
|
|
|
Map<String, Map<String, Double>> scoreMap = scoreResult.getScoreMap();
|
|
|
+ String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
|
|
|
+ Map<Integer, AccountIndexReplacePoolConfig> indexReplacePoolConfigMap = accountContentPoolConfigService.getContentReplacePools(param.getAccountName());
|
|
|
|
|
|
- List<RankItem> items = CommonCollectionUtils.toList(scoreParam.getContents(), c -> {
|
|
|
+ List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> {
|
|
|
RankItem item = new RankItem();
|
|
|
item.setContent(c);
|
|
|
c.setScoreMap(scoreMap.get(c.getId()));
|
|
|
item.setScoreMap(scoreMap.get(c.getId()));
|
|
|
- double score = 0.0;
|
|
|
+ double score;
|
|
|
int index = weightService.getIndex(item.getContent().getContentPoolType(), contentPools);
|
|
|
- if (contentPools[2].equals(item.getContent().getContentPoolType())) {
|
|
|
+ if (contentPools[0].equals(item.getContent().getContentPoolType())) {
|
|
|
+ score = item.getScore(ScoreStrategyEnum.I2I_RECOMMEND_STRATEGY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.I2I_RECOMMEND_STRATEGY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.CATEGORY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.CATEGORY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.FLOW_CTL_DECREASE.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.CRAWLER_DAYS_DECREASE_V2_STRATEGY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.CRAWLER_DAYS_DECREASE_V2_STRATEGY.value());
|
|
|
+ if (item.getScore(ScoreStrategyEnum.PUBLISH_TIMES.value()) >= 0) {
|
|
|
+ score += item.getScore(ScoreStrategyEnum.VIEW_COUNT_RATE.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.VIEW_COUNT_RATE.value());
|
|
|
+ }
|
|
|
+ if (item.getScore(ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value()) == 0) {
|
|
|
+ score += hisFissionOpenRateMissingBaseline * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value());
|
|
|
+ }
|
|
|
+ } else if (contentPools[1].equals(item.getContent().getContentPoolType())) {
|
|
|
score = item.getScore(ScoreStrategyEnum.SIMILARITY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.SIMILARITY.value())
|
|
|
+ item.getScore(ScoreStrategyEnum.CATEGORY.value())
|
|
|
* weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
ScoreStrategyEnum.CATEGORY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.FLOW_CTL_DECREASE.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.CRAWLER_DAYS_DECREASE_STRATEGY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.CRAWLER_DAYS_DECREASE_STRATEGY.value());
|
|
|
+ if (item.getScore(ScoreStrategyEnum.PUBLISH_TIMES.value()) >= 0) {
|
|
|
+ score += item.getScore(ScoreStrategyEnum.VIEW_COUNT_RATE.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.VIEW_COUNT_RATE.value());
|
|
|
+ }
|
|
|
+ if (item.getScore(ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value()) == 0) {
|
|
|
+ score += hisFissionOpenRateMissingBaseline * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.HIS_FISSION_OPEN_RATE.value());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ score = item.getScore(ScoreStrategyEnum.SIMILARITY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.SIMILARITY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.CATEGORY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.CATEGORY.value())
|
|
|
+ + item.getScore(ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ * weightService.getWeight(param.getStrategy(), param.getGhId(), index,
|
|
|
+ ScoreStrategyEnum.ACCOUNT_USER_CATEGORY.value())
|
|
|
+ item.getScore(ScoreStrategyEnum.ACCOUNT_PRE_DISTRIBUTE.value())
|
|
|
+ item.getScore(ScoreStrategyEnum.PUBLISH_TIMES.value())
|
|
|
+ item.getScore(ScoreStrategyEnum.CRAWLER_DAYS_DECREASE_STRATEGY.value())
|
|
|
@@ -58,8 +128,14 @@ public class InfiniteRankStrategy implements RankStrategy {
|
|
|
item.setScore(score);
|
|
|
return item;
|
|
|
});
|
|
|
+ // 相似度评分为0 报警返回
|
|
|
+ List<Article> hisPublishFirstArticleList = articleRepository.getByGhIdAndItemIndexAndTypeEqualsAndStatusEquals(
|
|
|
+ param.getGhId(), 1, param.getType(), 1);
|
|
|
+ if (RankStrategy.SimilarityScoreZero(items, param, hisPublishFirstArticleList)) {
|
|
|
+ return new RankResult(result);
|
|
|
+ }
|
|
|
// 安全分降权
|
|
|
- RankService.safeScoreDecrease(items);
|
|
|
+ //RankService.safeScoreDecrease(items);
|
|
|
|
|
|
// 1 排序
|
|
|
Collections.sort(items, (o1, o2) -> -Double.compare(o1.getScore(), o2.getScore()));
|
|
|
@@ -75,9 +151,46 @@ public class InfiniteRankStrategy implements RankStrategy {
|
|
|
List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
|
|
|
data.add(c);
|
|
|
}
|
|
|
+ // 4 选文章
|
|
|
+ String[] publishPool = Arrays.copyOf(contentPools, contentPools.length);
|
|
|
+
|
|
|
+ // 头 次 选取头条内容池 第11、12条内容 如果内容不足12条返回空
|
|
|
+ List<Content> pool1 = contentMap.get(contentPools[0]);
|
|
|
+ if (CollectionUtils.isNotEmpty(pool1)) {
|
|
|
+ pool1 = RankService.contentSourceTypeFilter(param.getStrategy(), pool1, 1);
|
|
|
+ }
|
|
|
+ RankService.printSortLog(param.getStrategy(), param.getAccountName(), "头条", pool1);
|
|
|
+ if (CollectionUtils.isNotEmpty(pool1) && pool1.size() >= 12) {
|
|
|
+ // 选取第11、12条内容
|
|
|
+ result.add(pool1.get(10));
|
|
|
+ result.add(pool1.get(11));
|
|
|
+ } else {
|
|
|
+ RankStrategy.sendFeishuFirstPoolEmpty(param, contentPools[0]);
|
|
|
+ return new RankResult(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3-8
|
|
|
+ // RankService.commonAdd38Content(param, result, contentPools, contentMap, param.getStrategy());
|
|
|
+ List<Content> pool = contentMap.get(contentPools[2]);
|
|
|
+ RankService.printSortLog(param.getStrategy(), param.getAccountName(), "3-8", pool);
|
|
|
+ if (CollectionUtils.isNotEmpty(pool)) {
|
|
|
+ Integer videoSourceType = PublishPlanInputSourceTypesEnum.longArticleVideoPoolSource.getVal();
|
|
|
+ Queue<Content> videoPoolQueue = pool.stream().filter(o -> Objects.equals(o.getSourceType(), videoSourceType))
|
|
|
+ .collect(Collectors.toCollection(LinkedList::new));
|
|
|
+ Queue<Content> otherPoolQueue = pool.stream().filter(o -> !Objects.equals(o.getSourceType(), videoSourceType))
|
|
|
+ .collect(Collectors.toCollection(LinkedList::new));
|
|
|
+ for (int i = 3; i < param.getSize() + 1; i++) {
|
|
|
+ Integer sourceType = RankService.getStrategyPoolSourceType(param.getStrategy(), i);
|
|
|
+ if (Objects.equals(sourceType, videoSourceType) && !videoPoolQueue.isEmpty()) {
|
|
|
+ result.add(videoPoolQueue.poll());
|
|
|
+ } else if (!otherPoolQueue.isEmpty()) {
|
|
|
+ result.add(otherPoolQueue.poll());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- // 全部使用3-8内容池
|
|
|
- RankService.commonAdd38Content(param, result, contentPools, contentMap, param.getStrategy());
|
|
|
+ rankService.checkPublishContentStatus(result, contentMap, publishPool);
|
|
|
+ RankStrategy.deduplication(result, contentMap, publishPool);
|
|
|
|
|
|
return new RankResult(result);
|
|
|
}
|