【问题标题】:Serialize hive map column序列化 hive 映射列
【发布时间】:2020-05-03 04:17:47
【问题描述】:

是否有任何自定义 udf 或其他函数可用于序列化 hive map 字段,以便可以在 group by 和 join 条件中使用。

例如,我们有一个地图字段:

dim_map = {'dim_geo': 'San Francisco', 'dim_country': 'USA'}

因为想在这个字段上加入两个表。

【问题讨论】:

    标签: dictionary hive hiveql


    【解决方案1】:

    使用brickhouse udf将其转换为JSON字符串,下载源代码,编译,添加jar文件并创建函数,见Getting Started说明:

    add jar /path/brickhouse-0.7.0-SNAPSHOT.jar;  
    CREATE TEMPORARY FUNCTION to_json AS 'brickhouse.udf.json.ToJsonUDF';
    
    select to_json(dim_map) as dim_map_json
      from...
    

    更新:

    正如评论中提到的@rajnish,地图没有排序,这可能会导致比较转换为 JSON 的地图时出现问题。

    地图示例:

    with test_data as (
    select map('dim_geo', 'San Francisco', 'dim_country','USA') map1,
           map('dim_country','USA','dim_geo', 'San Francisco') map2
    
    )
    
    select map1, map2, 
           case when map1['dim_geo']     = map2['dim_geo']     
                 and map1['dim_country'] = map2['dim_country'] 
                then 'equal'
                else 'not equal' end as compare_maps
    from test_data;
    

    结果:

    map1    map2    compare_maps
    
    {"dim_geo":"San Francisco","dim_country":"USA"} {"dim_country":"USA","dim_geo":"San Francisco"} equal
    

    最好像本例那样比较每个值,或者使用 HashMap.equals 方法编写自己的 UDF。

    默认情况下,HashMap。 equals() 方法通过键值对比较两个哈希图。这意味着两个 hashmap 实例必须具有完全相同的键值对,并且两者的大小必须相同。键值对的顺序可以不同,并且在比较中不起作用。 How to compare two hashmaps in Java

    【讨论】:

    • 因为 map 是一个无序的列,我担心,我担心 json 字段可能有不同的列顺序。 (仅供参考:如果我使用强制转换 JSON 到 str 进行连接操作)
    • @rajnish 是的,地图是无序的,这可能会导致问题... JSON 已经是字符串
    • 感谢@leftjoin 添加更多详细信息。就我而言,dim_map 可以根据不同的场景包含不同的 (keys,value) 对。所以不可能在查询中比较值。我认为最好的选择是写一些 udf。
    • 我需要某种f(dim_map) --> val: string,它会根据一些排序的键或值生成 json。如果我要加入两个不同的表,那么它是一致的。
    • @rajnish 自己编写或修改brickhouse.udf.json.ToJsonUDF
    猜你喜欢
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2013-09-09
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    相关资源
    最近更新 更多