需要使用 Hive 数据构建 JSON 格式

Posted

技术标签:

【中文标题】需要使用 Hive 数据构建 JSON 格式【英文标题】:Need to frame a JSON format using Hive data 【发布时间】:2021-08-25 18:21:18 【问题描述】:

您能帮我解决以下要求吗?我有一个配置单元表数据并使用它来构建下面的 JSON。

------------------------
Table : global_product
-------------------------
------------------------------------------------------------------------
Columns             Datatypes
------------------------------------------------------------------------
AAA                 varchar(10)
BBB                 varchar(10)
GEOGRAPHIC          array<struct<CCC:double,DDD:double>>    

select 
AAA, 
BBB, 
GEOGRAPHIC 
from global_product;

o/p:

 ind, 
 hyd, 
 ["CCC":4.7,"DDD":7.6,"CCC":5.1,"DDD":7.5, "CCC":5.7,"DDD":9.5]

需要使用上列数据框出JSON格式

"GLOBAL":

"PRODUCTS":
        "
        "ITEMS":"AAA":"ind","BBB":"hyd",
        "GEOGRAPHIC":[
                        "CCC":45.78,"DDD":87.56,
                        "CCC":45.73,"DDD":97.59,
                        "CCC":45.73,"DDD":97.59
                    ]
                "
        

【问题讨论】:

【参考方案1】:

如果你对复杂类型没问题

struct<global: struct<products: struct<items: struct<AAA:double, BBB:double>,
                                      geographic: array< struct<ccc: double, ddd: double> >
                                      >
                   > 
      > 

然后你可以使用 named_struct() 构造。在这种情况下,所有属性名称都将小写。

演示

with your_data as (--This is initial data example
select 'ind' as AAA, 'hyd' as BBB, 
array(named_struct("CCC",4.7,"DDD",7.6),named_struct("CCC",5.1,"DDD",7.5), named_struct("CCC",5.7,"DDD",9.5)) as GEOGRAPHIC
)

select named_struct('GLOBAL', named_struct('PRODUCTS',named_struct('ITEMS', named_struct('AAA', AAA, 'BBB', BBB), 
                                            'GEOGRAPHIC', GEOGRAPHIC) 
                                          )  
                   )
     from your_data;

结果(打印不漂亮):

"global":"products":"items":"aaa":"ind","bbb":"hyd","geographic":["ccc":4.7,"ddd":7.6,"ccc":5.1,"ddd":7.5,"ccc":5.7,"ddd":9.5] 

如果你对这样复杂的类型不满意,并且想要拥有像你一样的属性不小写的字符串,那么爆炸数组并连接所有内容

set hive.execution.engine=mr;
with your_data as (--This is initial data example, use your table instead of this example
select 'ind' as AAA, 'hyd' as BBB, 
array(named_struct("CCC",4.7,"DDD",7.6),named_struct("CCC",5.1,"DDD",7.5), named_struct("CCC",5.7,"DDD",9.5)) as GEOGRAPHIC
)

select    concat('"GLOBAL":\n\n"PRODUCTS":\n          "\n    "ITEMS":"AAA":"',AAA,'","BBB":"',BBB,'",', '\n',
          concat('     "GEOGRAPHIC": [\n         ',concat_ws(',',collect_list(concat('"CCC": "',e.CCC, '", "DDD": "',DDD,'"'))),
                 '\n          ]\n     "\n ') 
          )
     from your_data --replace with your table name
          lateral view outer inline(GEOGRAPHIC) e as CCC, DDD
          group by AAA, BBB;

结果:

"GLOBAL":

"PRODUCTS":
          "
    "ITEMS":"AAA":"ind","BBB":"hyd",
     "GEOGRAPHIC": [
         "CCC": "4.7", "DDD": "7.6","CCC": "5.1", "DDD": "7.5","CCC": "5.7", "DDD": "9.5"
          ]
     "
 

只需在 FROM 中使用您的表格而不是 CTE,它就可以处理您的数据。我添加了换行符 \n 和空格以产生类似的格式。

【讨论】:

非常感谢您的即时回复。第二个输出对我来说似乎很好。我对此有一个小小的澄清。按AAA分组,BBB在那里完成。但对我来说,group by 应该由 AAA 完成,并且选择列需要有 AAA、BBB。在这种情况下,应该怎么做,如果您提供任何建议,将会有所帮助。 @Sr4 为什么我在 groupby 中添加了 AAA 和 BBB?因为有聚合(collect_list),并且查询中使用的所有未聚合的列(它们是 AAA 和 BBB)都应该在 groupby 中。但是,如果您需要在 diggerent 组(仅限 AAA)上聚合并拥有这些列 AAA 和 BBB,那么解决方案是使用分析函数而不是简单的 groupby 聚合:collect_list(blabla) over(partition by AAA) - 这将导致数据集具有相同列表的相同 AAA , 行未分组。 @Sr4 之后,您可能希望执行额外的聚合,例如 min/max / 或简单的 groupby 或 row_number 以在上子查询中进行过滤,等在上子查询中进行过滤,以在必要时减少行,无论您想要聚合什么并且只有在那之后使用 concat 构建你的字符串。 @Sr4 欢迎您!请避免在 cmets 中提出其他问题。我们不是免费的编码服务。我为您提供了想法,并在您最初的问题上花了足够的时间。如果有用,请考虑采纳。如果您有任何其他问题,请再创建一个问题,描述问题并展示您的努力。社区中的某个人可能会帮助它发现您的问题很有趣 感谢您的回复。会努力的

以上是关于需要使用 Hive 数据构建 JSON 格式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JSON 格式备份和恢复 Flutter Hive 数据?

HIVE json格式数据的处理

hive表加载csv格式数据或者json格式数据

大数据Hive JSON数据处理

hive 非正确json格式字段造成查询错误

Hive处理Json数据详解