在spark计算当中,我们日常有些简单需求,比如去重,比如有四列(appid、date、type、platform),我们只需要对appid,date进行去重,另外两列不关注。在spark中,distinct会对所有列执行去重操作,两行比较,只要有个一列有差异,就不算重复。
要解决,只对某几列进行去重,可以使用Top N 的思路,也就是先分组,分组后,我们只取row_num=1第一行就可以了。
具体实现代码如下:
//选出某几列,去掉空值
Dataset dataset = input.select(
Consts.Fields.APPID,
Consts.Fields.EXT
A
D
I
D
)
.
n
a
(
)
.
d
r
o
p
(
d
r
o
p
N
u
l
C
o
l
)
;
d
a
t
a
s
e
t
.
p
e
r
s
i
s
t
(
)
;
/
/
设
置
窗
口
计
算
,
可
以
指
定
多
个
列
为
p
a
r
t
i
t
i
o
n
B
y
,
其
实
就
是
多
个
g
r
o
u
p
b
y
分
组
列
W
i
n
d
o
w
S
p
e
c
w
=
W
i
n
d
o
w
.
p
a
r
t
i
t
i
o
n
B
y
(
C
o
n
s
t
s
.
F
i
e
l
d
s
.
A
P
P
I
D
)
.
o
r
d
e
r
B
y
(
c
o
l
(
"
c
o
u
n
t
"
)
.
d
e
s
c
(
)
)
;
/
/
只
取
r
o
w
n
u
m
=
1
,
那
就
是
t
o
p
N
,
如
果
w
i
n
d
o
w
里
有
o
r
d
e
r
b
y
排
序
的
话
。
D
a
t
a
s
e
t
<
R
o
w
>
t
o
p
=
c
o
u
n
t
.
w
i
t
h
C
o
l
u
m
n
(
"
r
n
"
,
r
o
w
n
u
m
b
e
r
(
)
.
o
v
e
r
(
w
)
)
.
w
h
e
r
e
(
c
o
l
(
"
r
n
"
)
.
ADID ).na().drop(dropNulCol); dataset.persist(); //设置窗口计算,可以指定多个列为partitionBy,其实就是多个groupby 分组列 WindowSpec w=Window.partitionBy(Consts.Fields.APPID).orderBy(col("count").desc()); //只取row num=1,那就是top N,如果window里有orderby排序的话。 Dataset<Row> top = count.withColumn("rn",row_number().over(w)).where(col("rn").
ADID).na().drop(dropNulCol);dataset.persist();//设置窗口计算,可以指定多个列为partitionBy,其实就是多个groupby分组列WindowSpecw=Window.partitionBy(Consts.Fields.APPID).orderBy(col("count").desc());//只取rownum=1,那就是topN,如果window里有orderby排序的话。Dataset<Row>top=count.withColumn("rn",rownumber().over(w)).where(col("rn").eq
e
q
eq
eqeq(1)).drop(“rn”);