【问题标题】:Hadoop/Hive Collect_list without repeating itemsHadoop/Hive Collect_list 不重复项
【发布时间】:2015-09-28 06:11:44
【问题描述】:

根据Hive 0.12 - Collect_list 的帖子,我正在尝试查找 Java 代码以实现一个 UDAF,该代码将完成此功能或类似功能,但没有重复序列。

例如,collect_all() 返回一个序列 A, A, A, B, B, A, C, C 我想返回序列A, B, A, C。顺序重复的项目将被删除。

有谁知道 Hive 0.12 中将完成或编写自己的 UDAF 的函数?

一如既往,感谢您的帮助。

【问题讨论】:

    标签: hadoop hive hiveql


    【解决方案1】:

    如果你有这样的事情

    index  value
    1       A
    2       A
    3       A
    4       B
    5       B
    6       A
    7       c
    8       c
    

    其中 index 是一些排名顺序值,例如直接索引或日期之类的东西。我认为在你的情况下顺序很重要。

    然后查询:

    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 or nextvalue为null,你应该有结果。

    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"]

    【讨论】:

    • 第二个last_value() 部分的desc 部分有问题。实际错误是,cannot recognize input near 'rows' 'desc' 'between' in window_range_expression. 有什么想法吗?我删除了desc 只是为了看看它是否有效并且确实有效,但这显然不会返回所需的结果。
    • @user2715877 我做了一个应该有帮助的更改,但我没有在工作进行测试。祝你好运。
    • @invokethesheel 会试一试的。
    【解决方案2】:

    不久前我遇到了类似的问题。我不想写完整的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 不需要按照它们分组的顺序来保持列表中的元素;砖房collect 将。希望这会有所帮助。

    【讨论】:

    • 在 Java 工程师的帮助下,我能够让它工作。将 remove_seq_dups 放入 concat_ws 中,就有了完美的列表。谢谢。
    猜你喜欢
    • 2021-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-10-22
    • 2019-05-24
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多