Hadoop/Hive Collect_list 无重复项
Hadoop/Hive Collect_list without repeating items
基于 post、Hive 0.12 - Collect_list,我试图找到 Java 代码来实现一个 UDAF,它将完成这个或类似的功能,但没有重复序列。
例如,collect_all()
returns 一个序列 A, A, A, B, B, A, C, C
我想要返回序列 A, B, A, C
。依次重复的项目将被删除。
有谁知道 Hive 0.12 中的函数可以完成或已经编写了他们自己的 UDAF?
一如既往,感谢您的帮助。
如果你有这样的东西
index value
1 A
2 A
3 A
4 B
5 B
6 A
7 c
8 c
其中索引是一些排名顺序值,例如直接索引或日期之类的东西。我假设在您的情况下顺序很重要。
然后查询:
select collect_all(value)
from
(select index, value
from table) a
left outer join
(select index,
last_value(value) over (order by index row between current row and 1 following) as nextvalue
from table) b
on a.index=b.index
where value <> nextvalue
;
这里的问题是你得不到 C 的最后一个值,因为没有下一个值,所以 add 或 nextvalue 为空,你应该有结果。
select collect_all(value)
from
(select index, value
from table) a
left outer join
(select index,
last_value(value) over (order by index row between current row and 1 following) as nextvalue
from table) b
on a.index=b.index
where (value <> nextvalue) or (nextvalue is null)
;
这应该会产生 ["A"、"B"、"A"、"C"]
我 运行 前段时间遇到过类似的问题。我不想写一个完整的 UDAF
,所以我只是用 brickhouse collect 和我自己的 UDF
做了一个组合。假设你有这个数据
id value
1 A
1 A
1 A
1 B
1 B
1 A
1 C
1 C
1 D
2 D
2 D
2 D
2 D
2 F
2 F
2 F
2 A
2 W
2 A
我的UDF
是
package com.something;
import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class RemoveSequentialDuplicates extends UDF {
public ArrayList<Text> evaluate(ArrayList<Text> arr) {
ArrayList<Text> newList = new ArrayList<Text>();
newList.add(arr.get(0));
for (int i=1; i<arr.size(); i++) {
String front = arr.get(i).toString();
String back = arr.get(i-1).toString();
if (!back.equals(front)) {
newList.add(arr.get(i));
}
}
return newList;
}
}
然后我的查询是
add jar /path/to/jar/brickhouse-0.7.1.jar;
add jar /path/to/other/jar/duplicates.jar;
create temporary function remove_seq_dups as 'com.something.RemoveSequentialDuplicates';
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
select id
, remove_seq_dups(value_array) no_dups
from (
select id
, collect(value) value_array
from db.table
group by id ) x
输出
1 ["A","B","A","C","D"]
2 ["D","F","A","W","A"]
顺便说一句,内置的 collect_list
不需要按照分组的顺序保留列表的元素; brickhouse collect
会。希望这有帮助。
基于 post、Hive 0.12 - Collect_list,我试图找到 Java 代码来实现一个 UDAF,它将完成这个或类似的功能,但没有重复序列。
例如,collect_all()
returns 一个序列 A, A, A, B, B, A, C, C
我想要返回序列 A, B, A, C
。依次重复的项目将被删除。
有谁知道 Hive 0.12 中的函数可以完成或已经编写了他们自己的 UDAF?
一如既往,感谢您的帮助。
如果你有这样的东西
index value
1 A
2 A
3 A
4 B
5 B
6 A
7 c
8 c
其中索引是一些排名顺序值,例如直接索引或日期之类的东西。我假设在您的情况下顺序很重要。
然后查询:
select collect_all(value)
from
(select index, value
from table) a
left outer join
(select index,
last_value(value) over (order by index row between current row and 1 following) as nextvalue
from table) b
on a.index=b.index
where value <> nextvalue
;
这里的问题是你得不到 C 的最后一个值,因为没有下一个值,所以 add 或 nextvalue 为空,你应该有结果。
select collect_all(value)
from
(select index, value
from table) a
left outer join
(select index,
last_value(value) over (order by index row between current row and 1 following) as nextvalue
from table) b
on a.index=b.index
where (value <> nextvalue) or (nextvalue is null)
;
这应该会产生 ["A"、"B"、"A"、"C"]
我 运行 前段时间遇到过类似的问题。我不想写一个完整的 UDAF
,所以我只是用 brickhouse collect 和我自己的 UDF
做了一个组合。假设你有这个数据
id value
1 A
1 A
1 A
1 B
1 B
1 A
1 C
1 C
1 D
2 D
2 D
2 D
2 D
2 F
2 F
2 F
2 A
2 W
2 A
我的UDF
是
package com.something;
import java.util.ArrayList;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class RemoveSequentialDuplicates extends UDF {
public ArrayList<Text> evaluate(ArrayList<Text> arr) {
ArrayList<Text> newList = new ArrayList<Text>();
newList.add(arr.get(0));
for (int i=1; i<arr.size(); i++) {
String front = arr.get(i).toString();
String back = arr.get(i-1).toString();
if (!back.equals(front)) {
newList.add(arr.get(i));
}
}
return newList;
}
}
然后我的查询是
add jar /path/to/jar/brickhouse-0.7.1.jar;
add jar /path/to/other/jar/duplicates.jar;
create temporary function remove_seq_dups as 'com.something.RemoveSequentialDuplicates';
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
select id
, remove_seq_dups(value_array) no_dups
from (
select id
, collect(value) value_array
from db.table
group by id ) x
输出
1 ["A","B","A","C","D"]
2 ["D","F","A","W","A"]
顺便说一句,内置的 collect_list
不需要按照分组的顺序保留列表的元素; brickhouse collect
会。希望这有帮助。