1、原始数据
09308831030|930|2012.01.20 21:35:28|0c:56:5c:1e:b8:45|100004475|2|2
09308831030|930|2012.01.20 21:35:28|10:77:b0:9a:61:f6|100004471|3|1
09308831030|930|2012.01.20 21:35:28|00:07:63:1e:b8:45|100004476|1|3
09305410209|930|2014.08.07 15:10:24|FC:B0:C4:BB:98:4A|100004471|1|1
2、要求
按照第一个字段对数据去重,若数据重复,则按照最后两个字段保留最大值,并且第四和第五个字段根据第六和第七字段取相应的值(比如以上数据中第二条数据的第六个字段为3,是最大的一个,则第五个字段就去第二条数据中的第五个字段。第三条数据的第七个字段为3,是最大的一个,则第四个字段就去第三条数据中的第四个字段)。
预期输出结果为:
09308831030|930|2012-01-20 21:35:28|10:77:b0:9a:61:f6|100004476|3|3
09305410209|930|2014-08-07 15:10:24|FC:B0:C4:BB:98:4A|100004471|1|1
3.使用groupByKey实现
val step1= inputRdd.map(log => {
val valueItems = log.split(Utils.SplitValue, -1)
var userId = valueItems(0)
var stbId = valueItems(3)
var productCode = valueItems(4)
var createDate = valueItems(2)
var areaCode = valueItems(1)
var userType=valueItems(5)
var stbType=valueItems(6)
Some(userId, createDate, stbId, areaCode, productCode,userType,stbType)
}).filter(item => item.isDefined).map(item => item.get)
val step2 = step1.map(item=>{
val userId = item._1
val createDate = item._2
val stbId = item._3
val areaCode = item._4
val productCode = item._5
val userType=item._6
val stbType=item._7
(userId,(createDate,stbId,areaCode,productCode,userType,stbType))
}).groupByKey.map(item=> {
var userId=item._1
val value=item._2 .toArray
var createDate =value(0)._1
var stbId =value(0)._2
var areaCode =value(0)._3
var productCode = value(0)._4
var userType=value(0)._5
var stbType=value(0)._6
for(elem <-value){
if (elem._6 > stbType) {
stbId=elem._2
stbType=elem._6
}
if (elem._5>userType) {
productCode=elem._4
userType=elem._5
}
}
(userId,createDate,stbId,areaCode,productCode,userType,stbType)
})
val step3 = step2.map(item => {
val userId = item._1
val createDate = item._2
val stbId = item._3
val areaCode = item._4
val productCode = item._5
val userType=item._6
val stbType=item._7
s"${userId}
|${createDate}|${stbId}|${areaCode}|${productCode}|${userType}|${stbType}"
}).repartition(1).saveAsTextFile(output)
4、输出结果
itv09308831030|2012-01-20 21:35:28|10:77:b0:9a:61:f6|930|100004476|3|3
itv09305410209|2014-08-07 15:10:24|FC:B0:C4:BB:98:4A|930|100004471|1|1
5、若value中都是int类型的值,则可以用reduceByKey实现以上要求
若预期输出结果为:
itv09308831030|3|3
itv09305410209|1|1
则可用reduceByKey实现,具体代码如下:
val step2 = step1.map(item=>{
val userId = item._1
val userType=item._7
val stbType=item._8
(userId,(userType,stbType))
}).reduceByKey((x,y)=>{
var userType=0
var stbType=0
if(x._1>y._1) userType=x._1 else userType=y._1
if(x._2>y._2) stbType=x._1 else stbType=y._1
(userType,stbType)
}).map(item=>{
val userId=item._1
val userType=item._2._1
val stbType=item._2._2
(userId,userType,stbType)
})
val step3 = step2.map(item => {
val userId = item._1
val userType = item._2
val stbType = item._3
s"${userId}|${userType}|${stbType}"
}).repartition(1).saveAsTextFile(output)