- 1.需求
要求根据用户不同的学习时长来进行排序。
优先根据学习时长排序,如果学习1时长相等,在根据学习2时长进行排序
数据格式:
模拟数据:分别为时间戳-用户id--学习1时长--学习2时长
1519908784338 aa 7 5
1519906384338 aa 8 9
1519908544338 bb 36 1
1519908244338 aa 2 1
1519910824338 cc 34 38
1519911304338 cc 6 9
1519908064338 aa 10 7
1519909564338 aa 10 0
1519907164338 aa 3 6
1519905904339 bb 40 9
- 2.代码实现
代码实现思路:
- 2.1.先将数据转换成 (id,(time,first,second))的类型格式
- 2.2.通过reduceByKey 对数据进行聚合,取最小时间,first数据的总和,second数据的总和
- 2.3.通过LogSortKey中做二次排序的判断。
- 2.4.通过sortByKey 对数据进行排序
package spark_case import org.apache.spark.{SparkConf, SparkContext} /** * 优先第一种数据排序,如果相等,在根据第二种数据进行排序 */ object LogCase { def main(args: Array[String]): Unit = { //配置信息类 val conf=new SparkConf().setAppName("logSS").setMaster("local") //上下文对象 val sc:SparkContext= new SparkContext(conf) val records= sc.textFile("/home/wxp/files/case/test.log") val data=records.map{l=> val array=l.split("\t") val pair = Array(array(0).toLong,array(2).toLong,array(3).toLong) (array(1).toString,pair) } println(data.first()) //聚合操作,根据id ,计算总量 ,时间P val map=data.reduceByKey{(x,y)=> if(y(0)<x(0)) y(0) else x(0) y(2)=x(2)+y(2) y(1)=x(1)+y(1) y } val mapWithSortKey = map.map{ line=> val key=new LogSortKey(line._2(1),line._2(2)) println(line._1+"--"+line._2.toBuffer+"--"+key) (key,line._1) } val sorted=mapWithSortKey.sortByKey(false) val result=sorted.map(item=>item._2) result.collect().foreach(println) } }
运行上面代码就可以看到结果了
------------------------------ 下面 辅助类 或 法--------------------- -----------------
LogSortKey:辅助,做二次排序的判断。
package spark_case class LogSortKey(val first:Long,val second:Long) extends Ordered[AppvisitLogSortKey] with Serializable{ override def compare(that: AppvisitLogSortKey): Int = { // 按第一列数据排序,如果第一列数据相等,按第二列数据进行排序 if(this.first > that.first || (this.first == that.first && this.second > that.second)) { return 1 }else if(this.first < that.first || (this.first == that.first && this.second < that.second)) { return -1 }else{ return 0 } } }
- 3.模拟数据 log 生成类(JAVA编写)
package test; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.*; public class GenerateLog { public static void main(String[] args) { GenerateTestLog(); } private static void GenerateTestLog(){ List<String> userIds=new ArrayList<String>(); userIds.add("aa"); userIds.add("bb"); userIds.add("cc"); Random random =new Random(); StringBuffer buffer=new StringBuffer(""); for (int i = 0; i <10 ; i++) { Calendar cal=Calendar.getInstance(); cal.setTime(new Date()); cal.add(Calendar.MINUTE,random.nextInt(100)); long timeStamp=cal.getTime().getTime(); String userId=userIds.get(random.nextInt(3)); long first=random.nextInt(10); long second=random.nextInt(10); buffer.append(timeStamp).append("\t") .append(userId).append("\t") .append(first).append("\t") .append(second).append("\n"); } PrintWriter pw=null; try { pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream("/home/wxp/files/case/test.log"))); pw.write(buffer.toString()); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { pw.close(); }