如何保证hive collect_set 元素是有序的

背景:开发过程中遇到一个场景,就是要保证拼接起来的json是按照json里的某个字段排序的,我们这里是按照省市的数量来保证拼接起来的json是倒序的,我先展示下结果,以便于理解:

{
    "name": "广东",
    "number": 9999999,
    "value": [
        113.264434,
        23.129162
    ]
},
{
    "name": "安徽",
    "number": 999998,
    "value": [
        117.283042,
        31.861190
    ]
},
{
    "name": "河南",
    "number": 34565,
    "value": [
        113.624946,
        34.747040
    ]
},

拼接起来的json是按照number来倒序的。

本着可以用sql解决的事情就不要用别的语言来解决,否则会增加解决问题的复杂度,这里就用到了collect_set ,但是有个问题就是collect_set 拼接起来的数据是无序的,无法保证顺序,所以这里就要结合distribute by 和 sort by 一起来解决问题。上代码:

select 
    concat_ws(',',collect_set(strs))
from 
(select 
    cnt,
    strs
from 
(select 
    cnt ,
    concat('{','\"name\":','\"',province,'\"',',','\"number\":',cnt,',','\"value\":','[',longitude,',',latitude,']','}') as strs
from tblname 
order by cnt desc)t1   --先做了一次排序了已经
    distribute by strs
    sort by cnt desc )t2
;

以上仅供参考~

加上一段解释吧友好些:

其目的是从 tblname 表中提取一组按 cnt 字段降序排列的 JSON 格式的字符串集合。代码主要分为以下几个步骤:

  1. 子查询 t1: 首先,从 tblname 表中选择 cnt 和 province 列,并构造一个 JSON 格式的字符串 strs。每个 strs 字符串包含 name(省份名)、number(对应 cnt 值)和 value(由经度 longitude 和纬度 latitude 构成的数组)。子查询 t1 结果按 cnt 字段降序排列。
SELECT cnt, concat('{','\"name\":','\"',province,'\"',',','\"number\":',cnt,',','\"value\":','[',longitude,',',latitude,']','}') AS strs FROM tblname ORDER BY cnt DESC
  1. DISTRIBUTE BY strs: 对子查询 t1 的结果应用 DISTRIBUTE BY 子句,将数据分发到不同的 reducer(或计算节点),使得具有相同 strs 值的行被发送到同一个 reducer。请注意,DISTRIBUTE BY 不影响行的全局排序。

  2. SORT BY cnt DESC: 在每个 reducer 上,对收到的行进行局部排序,依据 cnt 字段进行降序排列。由于 DISTRIBUTE BY strs 已经确保了相同 strs 值的行被聚集在一起,这里 SORT BY cnt DESC 主要是对这些行内部按照 cnt 进行重新排序。

  3. 主查询: 最后,对所有 reducer 返回的结果进行汇总。由于每个 reducer 内部的行已经是按 cnt 降序排列的,使用 collect_set(strs) 函数收集所有 reducer 返回的 strs 字符串,并用 concat_ws(',', collect_set(strs)) 将这些字符串以逗号分隔的方式合并成一个单一的字符串。

综上所述,这段代码通过子查询 t1 先对原始数据按 cnt 进行全局降序排序,然后在每个 reducer 上对具有相同 strs 值的行进行局部降序排序。最后,主查询收集并合并这些已排序的 strs 字符串。尽管 DISTRIBUTE BY 和 SORT BY 会影响数据在 reducers 之间的分布和局部排序,但原始数据在子查询 t1 中已经进行了全局的 cnt 降序排序,因此最终得到的字符串集合中的元素(JSON 字符串)仍然是按照 cnt 值的降序排列的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值