Explorar o código

add recommend trace id

丁云鹏 hai 11 meses
pai
achega
1f95a9e087

+ 1 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/RankParam.java

@@ -13,4 +13,5 @@ public class RankParam {
     private String accountName;
     private List<Content> contents;
     private int size;
+    private String strategy;
 }

+ 11 - 126
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/RankService.java

@@ -1,24 +1,12 @@
 package com.tzld.longarticle.recommend.server.service.rank;
 
 
-import com.tzld.longarticle.recommend.server.model.Content;
-import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
-import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
-import com.tzld.longarticle.recommend.server.service.score.ScoreResult;
-import com.tzld.longarticle.recommend.server.service.score.ScoreService;
-import com.tzld.longarticle.recommend.server.service.score.strategy.SimilarityStrategy;
-import com.tzld.longarticle.recommend.server.service.score.strategy.ViewCountStrategy;
-import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
-import com.tzld.longarticle.recommend.server.util.JSONUtils;
-import com.tzld.longarticle.recommend.server.util.TitleSimilarCheckUtil;
+import com.tzld.longarticle.recommend.server.service.ServiceBeanFactory;
+import com.tzld.longarticle.recommend.server.service.rank.strategy.DefaultRankStrategy;
+import com.tzld.longarticle.recommend.server.service.rank.strategy.RankV2Strategy;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.lang3.RandomUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.*;
-
 /**
  * @author dyp
  */
@@ -26,122 +14,19 @@ import java.util.*;
 @Slf4j
 public class RankService {
 
-    @Autowired
-    private ScoreService scoreService;
-    @Autowired
-    private AccountContentPoolConfigService accountContentPoolConfigService;
-
     public RankResult rank(RankParam param) {
-
-        log.info("RankParam {}", JSONUtils.toJson(param));
-        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
-        log.info("ScoreResult {}", JSONUtils.toJson(scoreResult));
-
-        Map<String, Map<String, Double>> scoreMap = scoreResult.getScoreMap();
-
-        List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> {
-            RankItem item = new RankItem();
-            item.setContent(c);
-            item.setScoreMap(scoreMap.get(c.getId()));
-            return item;
-
-        });
-
-        // 1 排序
-        String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
-        Map<String, List<RankItem>> itemMap = new HashMap<>();
-        for (RankItem c : items) {
-            List<RankItem> data = itemMap.computeIfAbsent(c.getContent().getContentPoolType(), k -> new ArrayList<>());
-            data.add(c);
-        }
-        List<RankItem> sortedItems = new ArrayList<>();
-        for (int i = 0; i < contentPools.length; i++) {
-            if (i == 1) {
-                // 播放量排序
-                List<RankItem> data = itemMap.get(contentPools[i]);
-                if (CollectionUtils.isNotEmpty(data)) {
-                    Collections.sort(data, (o1, o2) -> -Double.compare(
-                            o1.getScore(ViewCountStrategy.class.getSimpleName()),
-                            o2.getScore(ViewCountStrategy.class.getSimpleName())));
-                    sortedItems.addAll(data);
-                }
-            } else {
-                // 相似排序
-                List<RankItem> data = itemMap.get(contentPools[i]);
-                if (CollectionUtils.isNotEmpty(data)) {
-                    Collections.sort(data, (o1, o2) -> -Double.compare(
-                            o1.getScore(SimilarityStrategy.class.getSimpleName()),
-                            o2.getScore(SimilarityStrategy.class.getSimpleName())));
-                    sortedItems.addAll(data);
-                }
-            }
-        }
-        List<Content> contents = CommonCollectionUtils.toList(sortedItems, RankItem::getContent);
-        log.info("Sort result {}", JSONUtils.toJson(contents));
-
-        // 3 相似去重
-        contents = deduplication(contents);
-        log.info("Deduplication {}", JSONUtils.toJson(contents));
-
-        // 4 文章按照内容池分组
-        Map<String, List<Content>> contentMap = new HashMap<>();
-        for (Content c : contents) {
-            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
-            data.add(c);
-        }
-        log.info("ContentMap {}", JSONUtils.toJson(contentMap));
-        // 5 按位置选文章
-        List<Content> result = new ArrayList<>();
-
-        // 头
-        List<Content> pool = contentMap.get(contentPools[0]);
-        if (CollectionUtils.isNotEmpty(pool)) {
-            result.add(pool.get(RandomUtils.nextInt(0, Math.min(pool.size(), 5))));
-        }
-
-        // 次
-        pool = contentMap.get(contentPools[1]);
-        if (CollectionUtils.isNotEmpty(pool)) {
-            result.add(pool.get(0));
-            if (result.size() == 1 && pool.size() > 1) {
-                result.add(pool.get(1));
-            }
-        }
-
-        // 3-8
-        pool = contentMap.get(contentPools[2]);
-        if (CollectionUtils.isNotEmpty(pool)) {
-            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
-        }
-
-        return new RankResult(result);
-    }
-
-    private ScoreParam convertToScoreParam(RankParam param) {
-        ScoreParam scoreParam = new ScoreParam();
-        scoreParam.setAccountName(param.getAccountName());
-        scoreParam.setContents(param.getContents());
-        return scoreParam;
+        RankStrategy strategy = getRankStrategy(param);
+        return strategy.rank(param);
     }
 
-    private List<Content> deduplication(List<Content> contents) {
-        List<String> titles = new ArrayList<>();
-        List<Content> result = new ArrayList<>();
-        // 遍历所有列表
-        for (Content c : contents) {
-            if (similarity(c.getTitle(), titles)) {
-                continue;
-            } else {
-                result.add(c);
-                titles.add(c.getTitle());
-            }
+    private RankStrategy getRankStrategy(RankParam param) {
+        switch (param.getStrategy()) {
+            case "ArticleRankV2":
+                return ServiceBeanFactory.getBean(RankV2Strategy.class);
+            default:
+                return ServiceBeanFactory.getBean(DefaultRankStrategy.class);
         }
-
-        return result;
     }
 
-    private boolean similarity(String title, List<String> titles) {
-        return TitleSimilarCheckUtil.isDuplicateContent(title, titles);
-    }
 
 }

+ 11 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/RankStrategy.java

@@ -0,0 +1,11 @@
+package com.tzld.longarticle.recommend.server.service.rank;
+
+
+/**
+ * @author dyp
+ */
+public interface RankStrategy {
+
+    RankResult rank(RankParam param);
+
+}

+ 151 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/DefaultRankStrategy.java

@@ -0,0 +1,151 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.AccountContentPoolConfigService;
+import com.tzld.longarticle.recommend.server.service.rank.RankItem;
+import com.tzld.longarticle.recommend.server.service.rank.RankParam;
+import com.tzld.longarticle.recommend.server.service.rank.RankResult;
+import com.tzld.longarticle.recommend.server.service.rank.RankStrategy;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreResult;
+import com.tzld.longarticle.recommend.server.service.score.ScoreService;
+import com.tzld.longarticle.recommend.server.service.score.strategy.SimilarityStrategy;
+import com.tzld.longarticle.recommend.server.service.score.strategy.ViewCountStrategy;
+import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
+import com.tzld.longarticle.recommend.server.util.JSONUtils;
+import com.tzld.longarticle.recommend.server.util.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class DefaultRankStrategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+    @Autowired
+    private AccountContentPoolConfigService accountContentPoolConfigService;
+
+    public RankResult rank(RankParam param) {
+
+        log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+        log.info("ScoreResult {}", JSONUtils.toJson(scoreResult));
+
+        Map<String, Map<String, Double>> scoreMap = scoreResult.getScoreMap();
+
+        List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> {
+            RankItem item = new RankItem();
+            item.setContent(c);
+            item.setScoreMap(scoreMap.get(c.getId()));
+            return item;
+
+        });
+
+        // 1 排序
+        String[] contentPools = accountContentPoolConfigService.getContentPools(param.getAccountName());
+        Map<String, List<RankItem>> itemMap = new HashMap<>();
+        for (RankItem c : items) {
+            List<RankItem> data = itemMap.computeIfAbsent(c.getContent().getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        List<RankItem> sortedItems = new ArrayList<>();
+        for (int i = 0; i < contentPools.length; i++) {
+            if (i == 1) {
+                // 播放量排序
+                List<RankItem> data = itemMap.get(contentPools[i]);
+                if (CollectionUtils.isNotEmpty(data)) {
+                    Collections.sort(data, (o1, o2) -> -Double.compare(
+                            o1.getScore(ViewCountStrategy.class.getSimpleName()),
+                            o2.getScore(ViewCountStrategy.class.getSimpleName())));
+                    sortedItems.addAll(data);
+                }
+            } else {
+                // 相似排序
+                List<RankItem> data = itemMap.get(contentPools[i]);
+                if (CollectionUtils.isNotEmpty(data)) {
+                    Collections.sort(data, (o1, o2) -> -Double.compare(
+                            o1.getScore(SimilarityStrategy.class.getSimpleName()),
+                            o2.getScore(SimilarityStrategy.class.getSimpleName())));
+                    sortedItems.addAll(data);
+                }
+            }
+        }
+        List<Content> contents = CommonCollectionUtils.toList(sortedItems, RankItem::getContent);
+        log.info("Sort result {}", JSONUtils.toJson(contents));
+
+        // 3 相似去重
+        contents = deduplication(contents);
+        log.info("Deduplication {}", JSONUtils.toJson(contents));
+
+        // 4 文章按照内容池分组
+        Map<String, List<Content>> contentMap = new HashMap<>();
+        for (Content c : contents) {
+            List<Content> data = contentMap.computeIfAbsent(c.getContentPoolType(), k -> new ArrayList<>());
+            data.add(c);
+        }
+        log.info("ContentMap {}", JSONUtils.toJson(contentMap));
+        // 5 按位置选文章
+        List<Content> result = new ArrayList<>();
+
+        // 头
+        List<Content> pool = contentMap.get(contentPools[0]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.add(pool.get(RandomUtils.nextInt(0, Math.min(pool.size(), 5))));
+        }
+
+        // 次
+        pool = contentMap.get(contentPools[1]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.add(pool.get(0));
+            if (result.size() == 1 && pool.size() > 1) {
+                result.add(pool.get(1));
+            }
+        }
+
+        // 3-8
+        pool = contentMap.get(contentPools[2]);
+        if (CollectionUtils.isNotEmpty(pool)) {
+            result.addAll(pool.subList(0, Math.min(pool.size(), param.getSize() - result.size())));
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (Content c : contents) {
+            if (similarity(c.getTitle(), titles)) {
+                continue;
+            } else {
+                result.add(c);
+                titles.add(c.getTitle());
+            }
+        }
+
+        return result;
+    }
+
+    private boolean similarity(String title, List<String> titles) {
+        return TitleSimilarCheckUtil.isDuplicateContent(title, titles);
+    }
+
+}

+ 104 - 0
long-article-recommend-service/src/main/java/com/tzld/longarticle/recommend/server/service/rank/strategy/RankV2Strategy.java

@@ -0,0 +1,104 @@
+package com.tzld.longarticle.recommend.server.service.rank.strategy;
+
+
+import com.tzld.longarticle.recommend.server.model.Content;
+import com.tzld.longarticle.recommend.server.service.rank.RankItem;
+import com.tzld.longarticle.recommend.server.service.rank.RankParam;
+import com.tzld.longarticle.recommend.server.service.rank.RankResult;
+import com.tzld.longarticle.recommend.server.service.rank.RankStrategy;
+import com.tzld.longarticle.recommend.server.service.score.ScoreParam;
+import com.tzld.longarticle.recommend.server.service.score.ScoreResult;
+import com.tzld.longarticle.recommend.server.service.score.ScoreService;
+import com.tzld.longarticle.recommend.server.service.score.strategy.SimilarityStrategy;
+import com.tzld.longarticle.recommend.server.service.score.strategy.ViewCountStrategy;
+import com.tzld.longarticle.recommend.server.util.CommonCollectionUtils;
+import com.tzld.longarticle.recommend.server.util.JSONUtils;
+import com.tzld.longarticle.recommend.server.util.TitleSimilarCheckUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author dyp
+ */
+@Service
+@Slf4j
+public class RankV2Strategy implements RankStrategy {
+
+    @Autowired
+    private ScoreService scoreService;
+
+    public RankResult rank(RankParam param) {
+
+        log.info("RankParam {}", JSONUtils.toJson(param));
+        ScoreResult scoreResult = scoreService.score(convertToScoreParam(param));
+        log.info("ScoreResult {}", JSONUtils.toJson(scoreResult));
+
+        Map<String, Map<String, Double>> scoreMap = scoreResult.getScoreMap();
+
+        List<RankItem> items = CommonCollectionUtils.toList(param.getContents(), c -> {
+            RankItem item = new RankItem();
+            item.setContent(c);
+            item.setScoreMap(scoreMap.get(c.getId()));
+            return item;
+
+        });
+
+        // 1 排序
+        Collections.sort(items, (o1, o2) -> {
+            int result = -Double.compare(
+                    o1.getScore(SimilarityStrategy.class.getSimpleName()),
+                    o2.getScore(SimilarityStrategy.class.getSimpleName()));
+            if (result != 0) {
+                return result;
+            }
+
+            return -Double.compare(
+                    o1.getScore(ViewCountStrategy.class.getSimpleName()),
+                    o2.getScore(ViewCountStrategy.class.getSimpleName()));
+        });
+        // 2 选文章
+        List<Content> result = new ArrayList<>();
+        if (CollectionUtils.isNotEmpty(items)) {
+            for (int i = 0; i < Math.min(items.size(), param.getSize()); i++) {
+                result.add(items.get(i).getContent());
+            }
+        }
+
+        return new RankResult(result);
+    }
+
+    private ScoreParam convertToScoreParam(RankParam param) {
+        ScoreParam scoreParam = new ScoreParam();
+        scoreParam.setAccountName(param.getAccountName());
+        scoreParam.setContents(param.getContents());
+        return scoreParam;
+    }
+
+    private List<Content> deduplication(List<Content> contents) {
+        List<String> titles = new ArrayList<>();
+        List<Content> result = new ArrayList<>();
+        // 遍历所有列表
+        for (Content c : contents) {
+            if (similarity(c.getTitle(), titles)) {
+                continue;
+            } else {
+                result.add(c);
+                titles.add(c.getTitle());
+            }
+        }
+
+        return result;
+    }
+
+    private boolean similarity(String title, List<String> titles) {
+        return TitleSimilarCheckUtil.isDuplicateContent(title, titles);
+    }
+
+}