经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
教你写一个电商商品排行榜功能
来源:cnblogs  作者:小码A梦  时间:2024/7/8 9:54:50  对本文有异议

在电商平台上,会有很有榜单的信息,比如新品榜、畅销榜。通过这些榜单,可以让用户直观的对比各个商品之间的销量对比,促使更多的用户下单或者加购。本文介绍如何实现一个简单的榜单功能

榜单定义

在某多 app 上,可以看到下面的小米手表排行榜:

需要实现几个功能:

  • 榜单是针对某类商品进行统计,比如手机排行是统计品类为手机的商品。
  • 排行统计可以是按照某一个维度,比如订单量、一个月回购量、或者几个指数汇总成一个分数进行排行。上图就是根据热卖指数进行排行。
  • 除了排行之外,还需要展示霸榜的天数,比如霸榜榜首 n 天、霸榜前三 n 天。上面排名第一就展示了霸榜榜首的天数。

榜单实现思路

统计榜单至少需要两张表,榜单主表和榜单明细表。

  • 主表记录榜单信息,比如xx月xx手机畅销榜,统计维度、统计时间范围等等。
  • 明细表主要记录,商品有信息、排行、统计销量、分数等信息。

创建好榜单之后,每天定时跑统计任务,将更新榜单明细表中。统计的维度,需要根据具体需求来查询数据库,然后在计算分数,最后计算排名。

以上实现比较简单,主要是去除相关数据进行汇总计算。最重要的一个功能就是霸榜天数的求解。

霸榜天数

霸榜分成两种:霸榜榜首 n 天、霸榜前三 n 天。这就需要多加一个表,榜单明细日志表,记录每天榜单明细。比如以下记录三天的榜单明细日志记录:

霸榜天数是从后往前统计,需要统计连续的天数,首先定位到最后一天,也就是4日,前三的商品 C、A、B 三个商品。统计榜首,就一直排在榜首,直到前面不是榜首的商品。比如上面的图中,4日榜首是商品 C,这就往前推算,3日是不是商品 C,如果不是霸榜1天。如果是的话,就继续往前查,天数累加,直到统计的是非商品。

霸榜前三就相对复杂一点,需要统计两个数据,也就是排名三的往前统计,因为榜首已经统计了,所以只需要统计第2和第3的商品,也就是商品 A 和商品 B。往前找数据:

统计榜首

创建榜单明细日志类:

  1. @Data
  2. @AllArgsConstructor
  3. class RankDetailLog{
  4. /**
  5. * 商品
  6. */
  7. private String product;
  8. /**
  9. * 排行
  10. */
  11. private Integer rank;
  12. /**
  13. * 时间
  14. */
  15. private String createTimeStr;
  16. }

创建模拟数据:

  1. RankDetailLog detailLog7 = new RankDetailLog("C",1,"7月4日");
  2. RankDetailLog detailLog8 = new RankDetailLog("A",2,"7月4日");
  3. RankDetailLog detailLog9 = new RankDetailLog("B",3,"7月4日");
  4. RankDetailLog detailLog1 = new RankDetailLog("D",1,"7月2日");
  5. RankDetailLog detailLog2 = new RankDetailLog("B",2,"7月2日");
  6. RankDetailLog detailLog3 = new RankDetailLog("C",3,"7月2日");
  7. RankDetailLog detailLog4 = new RankDetailLog("B",1,"7月3日");
  8. RankDetailLog detailLog5 = new RankDetailLog("C",2,"7月3日");
  9. RankDetailLog detailLog6 = new RankDetailLog("A",3,"7月3日");
  10. List<RankDetailLog> detailLogList = new ArrayList<>();
  11. detailLogList.add(detailLog1);
  12. detailLogList.add(detailLog2);
  13. detailLogList.add(detailLog3);
  14. detailLogList.add(detailLog4);
  15. detailLogList.add(detailLog5);
  16. detailLogList.add(detailLog6);
  17. detailLogList.add(detailLog7);
  18. detailLogList.add(detailLog8);
  19. detailLogList.add(detailLog9);

分组排序:

  1. // 按日期分组并排序
  2. Map<String, List<RankDetailLog>> sortedCreateTimeMap = detailLogList.stream()
  3. .collect(Collectors.groupingBy(RankDetailLog::getCreateTimeStr, () -> new TreeMap<>(Comparator.reverseOrder()), Collectors.toList()));

统计榜首:

  1. String topProduct = null;
  2. Integer topProductNum = 0;
  3. for (Map.Entry<String, List<RankDetailLog>> entry : sortedCreateTimeMap.entrySet()) {
  4. List<RankDetailLog> rankDetailLogList = entry.getValue();
  5. if (!rankDetailLogList.isEmpty()) {
  6. RankDetailLog topLog = rankDetailLogList.get(0);
  7. String currentTopProduct = topLog.getProduct();
  8. if (topProduct == null) {
  9. topProduct = currentTopProduct;
  10. topProductNum = 1;
  11. } else {
  12. if (topProduct.equals(currentTopProduct)) {
  13. topProductNum++;
  14. } else {
  15. break;
  16. }
  17. }
  18. }
  19. }
  20. System.out.println("榜首商品:" + topProduct + ",天数:" + topProductNum);

输出:C:1 表示商品霸榜榜首1天。

步骤详解:

  • topProduct 标记榜首商品,topProductNum 榜首天数记录。
  • 遍历集合,记录榜首商品,然后天数设置1。遍历数据,如果是连续的数据,数量 +1。找不到商品就结束遍历。

统计前三

前三的统计其实是排除了榜首,也就是只统计最新数据的第2和第3的商品。往前汇总统计。

  1. Set<String> threeProductSet = new HashSet<>();
  2. Map<String,Integer> threeProductMap = new HashMap<>();
  3. boolean first = true;
  4. for (Map.Entry<String, List<RankDetailLog>> entry : sortedCreateTimeMap.entrySet()) {
  5. List<RankDetailLog> rankDetailLogList = entry.getValue();
  6. if (!rankDetailLogList.isEmpty()) {
  7. // 只取前三数据
  8. rankDetailLogList = rankDetailLogList.subList(0,Math.min(3,rankDetailLogList.size()));
  9. if (first) {
  10. for (int i = 0; i < rankDetailLogList.size(); i++) {
  11. RankDetailLog detailLog = rankDetailLogList.get(i);
  12. String topThreeProduct = detailLog.getProduct();
  13. if (i >= 1) {
  14. threeProductSet.add(topThreeProduct);
  15. threeProductMap.put(topThreeProduct,0);
  16. }
  17. }
  18. first = false;
  19. } else {
  20. Set<String> currentThreeProductSet = new HashSet<>();
  21. for (RankDetailLog detailLog : rankDetailLogList) {
  22. String topThreeProduct = detailLog.getProduct();
  23. if (threeProductMap.containsKey(topThreeProduct)) {
  24. threeProductMap.put(topThreeProduct,threeProductMap.get(topThreeProduct) + 1);
  25. currentThreeProductSet.add(topThreeProduct);
  26. }
  27. }
  28. threeProductSet.removeAll(currentThreeProductSet);
  29. }
  30. }
  31. }
  32. System.out.println(threeProductMap);

输出:{A=2, B=3}

  • 获取到最新商品详情,统计第2和第3的商品,存 threeProductSet 以及计算器集合 threeProductMap 中。
  • 为了统计连续性,使用 currentThreeProductSet 存当天的商品信息,再和前面的商品交集,交集的数据就是有连续性商品数据。

总结

  • 商品榜单需要根据不同的统计维度、参数、统计时间来设计商品榜单表结构。再根据配置的信息,生成榜单详情信息。
  • 一般都使用定时方式生成榜单详情信息。
  • 需要统计连续霸榜天数,一般有两种方式,一种是统计榜首的连续天数,另一种是前三的连续天数。
    • 统计榜首首先获取最新的榜首商品,商品往前找,连续性的找到前面的数据,如果非连续性就查找结束。
    • 统计前三排除了榜首之外,就是统计第2和第3的商品。获取最新的商品并记录,往前遍历,使用 set 的存储每次遍历的商品,在使用集合的交集来保证统计的连续性。

原文链接:https://www.cnblogs.com/jeremylai7/p/18289233

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号