一、需求回顾 ---------------------------------------------------------- 1.计算出来通过筛选条件的那些session,他们访问过的所有品类(点击、下单、支付),按照各个品类的点击、下单和支付次数,降序排序, 获取前10个品类,也就是筛选条件下的那一批session的top10热门品类; 2.点击、下单和支付次数:优先按照点击次数排序、如果点击次数相等,那么按照下单次数排序、如果下单次数相当,那么按照支付次数排序 3.这个需求是很有意义的,因为这样,就可以让数据分析师、产品经理、公司高层,随时随地都可以看到自己感兴趣的那一批用户, 最喜欢的10个品类,从而对自己公司和产品的定位有清晰的了解,并且可以更加深入的了解自己的用户,更好的调整公司战略 二、思路分析 ------------------------------------------------------- 1.拿到通过筛选条件的那批session,访问过的所有品类 2.计算出session访问过的所有品类的点击、下单和支付次数,这里可能要跟第一步计算出来的品类进行join 3.自己开发二次排序的key 4.做映射,将品类的点击、下单和支付次数,封装到二次排序key中,作为PairRDD的key 5.使用sortByKey(false),按照自定义key,进行降序二次排序 6.使用take(10)获取,排序后的前10个品类,就是top10热门品类 7.将top10热门品类,以及每个品类的点击、下单和支付次数,写入MySQL数据库 8.本地测试 9.使用Scala来开发二次排序key 三、具体步骤 ------------------------------------------------------- 1.获取符合条件的session访问过的所有品类 a.首先拿到之前的两个RDD, filteredSessionid2AggrInfoRDD --> 根据taskparam过滤过后的<sessionid, fullaggrinfo> sessionid2actionRDD --> user_visit_action表的Row信息与sessionid的映射 b.因为要使用按照条件过滤后的sessionid2actionRDD,所以,拿filteredSessionid2AggrInfoRDD.join(sessionid2actionRDD) 得到<sesssionid,[fullaggrinfo,action_row]> rdd1 对rdd1进行mapToPair(),去掉fullaggrinfo,仅留下<sesssionid,action_row>的映射 从而得到符合条件的session访问过的所有品类sessionid2detailRDD <sesssionid,action_row> 2.获取符合条件的session访问过的所有品类id [访问过:指的是,点击过、下单过、支付过的品类] a.对sessionid2detailRDD应用flatMapToPair,得到JavaPairRDD<Long, Long> categoryidRDD 其中的<Long,Long> 为 点击的<clickCategoryId, clickCategoryId>,<orderCategoryId,orderCategoryId>,<payCategoryId,payCategoryId> b.这样就得到了符合条件的session所有访问过的商品品类id(点击过,订单过,支付过),用<Long,Long>表示categoryidRDD <Long,Long> c.至于为什么<clickCategoryId, clickCategoryId>,是为了以后的join用 3.计算各品类的点击、下单和支付的次数 a.计算各个品类的点击次数 对sessionid2detailRDD <sesssionid,action_row>应用filter,过滤掉action_row中click_category_id的字段为空的行,得到clickActionRDD 对clickActionRDD <sesssionid,action_row>应用mapToPair,每行都变换成<clickCategoryId,1> 最终得到<clickCategoryId,1> clickCategoryIdRDD 对<clickCategoryId,1> clickCategoryIdRDD应用reduceByKey,进行聚合,得到clickCategoryId和对应的count,JavaPairRDD<Long, Long> clickCategoryId2CountRDD b.计算各个品类的下单次数 同上得到JavaPairRDD<Long, Long> orderCategoryId2CountRDD c.计算各个品类的支付次数 同上得到JavaPairRDD<Long, Long> payCategoryId2CountRDD 4.join各品类与它的点击、下单和支付的次数 a.JavaPairRDD<Long, Tuple2<Long, Optional<Long>>> tmpJoinRDD = categoryidRDD.leftOuterJoin(clickCategoryId2CountRDD); b.对tmpJoinRDD进行mapToPair变换,得到<categoryId, "categoryid|clickCount"> tmpMapRDD,这样就将categoryidRDD的有点击的行,增加了点击次数 c.同上,对上面的tmpMapRDD,进行leftOuterJoin(orderCategoryId2CountRDD),然后mapToPair变换,得到新的 <categoryId, "categoryid|clickCount|orderCount"> tmpMapRDD c.同上,对上面的tmpMapRDD,进行leftOuterJoin(payCategoryId2CountRDD),然后mapToPair变换,得到新的 <categoryId, "categoryid|clickCount|orderCount|payCount"> tmpMapRDD d.最终得到<categoryId, "categoryid|clickCount|orderCount|payCount"> categoryid2countRDD 5.自定义二次排序key /* * * 封装你要进行排序算法需要的几个字段:点击次数、下单次数和支付次数 * 实现Ordered接口要求的几个方法 * * 跟其他key相比,如何来判定大于、大于等于、小于、小于等于 * * 依次使用三个次数进行比较,如果某一个相等,那么就比较下一个 */ public class CategorySortKey implements Ordered<CategorySortKey> { private long clickCount; private long orderCount; private long payCount; public boolean $greater(CategorySortKey other) { if(clickCount > other.getClickCount()) { return true; } else if(clickCount == other.getClickCount() && orderCount > other.getOrderCount()) { return true; } else if(clickCount == other.getClickCount() && orderCount == other.getOrderCount() && payCount > other.getPayCount()) { return true; } return false; } public boolean $greater$eq(CategorySortKey other) { if($greater(other)) { return true; } else if(clickCount == other.getClickCount() && orderCount == other.getOrderCount() && payCount == other.getPayCount()) { return true; } return false; } public boolean $less(CategorySortKey other) { if(clickCount < other.getClickCount()) { return true; } else if(clickCount == other.getClickCount() && orderCount < other.getOrderCount()) { return true; } else if(clickCount == other.getClickCount() && orderCount == other.getOrderCount() && payCount < other.getPayCount()) { return true; } return false; } public boolean $less$eq(CategorySortKey other) { if($less(other)) { return true; } else if(clickCount == other.getClickCount() && orderCount == other.getOrderCount() && payCount == other.getPayCount()) { return true; } return false; } public int compare(CategorySortKey other) { if(clickCount - other.getClickCount() != 0) { return (int) (clickCount - other.getClickCount()); } else if(orderCount - other.getOrderCount() != 0) { return (int) (orderCount - other.getOrderCount()); } else if(payCount - other.getPayCount() != 0) { return (int) (payCount - other.getPayCount()); } return 0; } public int compareTo(CategorySortKey other) { if(clickCount - other.getClickCount() != 0) { return (int) (clickCount - other.getClickCount()); } else if(orderCount - other.getOrderCount() != 0) { return (int) (orderCount - other.getOrderCount()); } else if(payCount - other.getPayCount() != 0) { return (int) (payCount - other.getPayCount()); } return 0; } public long getClickCount() { return clickCount; } public void setClickCount(long clickCount) { this.clickCount = clickCount; } public long getOrderCount() { return orderCount; } public void setOrderCount(long orderCount) { this.orderCount = orderCount; } public long getPayCount() { return payCount; } public void setPayCount(long payCount) { this.payCount = payCount; } } 6.将数据映射成<sortkey,info>格式的rdd,然后进行二次排序 a.对<categoryId, "categoryid|clickCount|orderCount|payCount"> categoryid2countRDD 应用mapToPair, 得到<CategorySortKey,countstr>格式的RDD sortKey2countRDD b.JavaPairRDD<CategorySortKey, String> sortedCategoryCountRDD = sortKey2countRDD.sortByKey(false); false表示降序 7.用take(10)取出top10热门品类,并写入MySQL List<Tuple2<CategorySortKey, String>> top10CategoryList = sortedCategoryCountRDD.take(10);
电商用户行为分析大数据平台(四)-- top10热门品类分析
猜你喜欢
转载自blog.csdn.net/xcvbxv01/article/details/86516112
今日推荐
周排行