首页 > 解决方案 > 从存储为 Hive 中的字符串的 JSON 对象替换特定元素

问题描述

我有一个配置单元表,其中一列具有字符串数据类型,它实际上存储了一个 json 对象。

我正在尝试在该表上触发 SELECT,但我只想替换 JSON 中的一个元素。例如,假设对于特定的配置单元行,保存 JSON 的列的值是:-

{  
    "employee": {  
        "name":       "sonoo",   
        "salary":     56000,   
        "married":    true  
    }  
}  

现在我想用 null(或空白等)替换元素 $.employee.name(当前值为“sonoo”)的值。所以选择语句应该返回以下内容

 {  
    "employee": {  
        "name":       null,   
        "salary":     56000,   
        "married":    true  
    }  
}  

有什么办法吗?

标签: hive

解决方案


如果您不想解析所有 JSON 元组并再次重新组装 JSON,那么这是使用 sing 的解决方案regex_replace

 with your_data as (
select stack (1,
'{  
    "employee": {  
        "name":       "sonoo",   
        "salary":     56000,   
        "married":    true  
    }  
}') as json_str
) --use you_table instead of this


 select regexp_replace(json_str,'(\\"employee\\":\\s*\\{\\s*\\"name\\":\\s*)(\\".*\\")([\\S\\s]*)','$1null$3') as json_str
  from your_data s;

结果:

OK
{
    "employee": {
        "name":       null,
        "salary":     56000,
        "married":    true
    }
}
Time taken: 0.074 seconds, Fetched: 1 row(s)

正则表达式中的第一组描述了要替换的值之前的所有内容:

(\\"employee\\":\\s*\\{\\s*\\"name\\":\\s*)- 方法:

\\"employee\\":- “员工”:字面意思,

\\s*- 任意数量的空格

\\{- { 特点

\\s*- 任意数量的空格

\\"name\\":- “姓名”:

\\s*- 任意数量的空格

为什么第一组的描述如此详细,包括员工密钥?为了确保我们将只替换员工嵌套结构中的名称值,而不是其他名称,它可以在其他嵌套结构中。

Secong 组是要替换的双引号中的字符串:(\\".*\\")

第三组是第二组之后的其他内容:([\\S\\s]*)- 任意数量的空格或非空格字符。如果 JSON 不包含换行符 \n,则只需 (.*) 即可,请自行测试

因此,正则表达式匹配整个 JSON,由三组组成。并且您将其替换为'$1null$3'- First groupnullThird group连接在一起。换句话说,第二组被替换为null,其他一切都原样。


推荐阅读