我有几个大的json对象(想想GB标度),其中一些最里层的对象值是对象数组。我正在使用jq 1.4而我试图将这些数组分解为单个对象,每个对象都有一个键,例如g__0或g__1,其中数字对应于原始数组中的索引,如返回通过keys
函数。每个数组中的对象数量可以任意大(在我的例子中它等于3)。同时我想保留剩下的结构。
对于它的价值,原始结构来自MongoDB,但我无法在此级别更改它。然后,我将使用此json文件为BigQuery创建模式,其中示例列将为seeds.g__1.guid
,依此类推。
我有什么:
{
"port": 4500,
"notes": "This is an example",
"seeds": [
{
"seed": 12,
"guid": "eaf612"
},
{
"seed": 23,
"guid": "bea143"
},
{
"seed": 38,
"guid": "efk311"
}
]
}
我希望实现的目标:
{
"port": 4500,
"notes": "This is an example",
"seeds": {
"g__0": {
"seed": 12,
"guid": "eaf612"
},
"g__1": {
"seed": 23,
"guid": "bea143"
},
"g__2": {
"seed": 38,
"guid": "efk311"
}
}
}
谢谢!
答案 0 :(得分:1)
因此,您基本上希望在BigQuery Table中转置(透视)您的数据,而不是将数据放在行中,如下所示
您的数据如下所示
因此,我的建议是 首先,按原样加载您的数据 所以现在,不要在BigQuery之外进行模式转换,而是在BigQuery中做它!
下面是如何实现您正在寻找的转换的示例(假设您在阵列中有最多三个项目/对象)
#standardSQL
SELECT
port, notes,
STRUCT(
seeds[SAFE_OFFSET(0)] AS g__0,
seeds[SAFE_OFFSET(1)] AS g__1,
seeds[SAFE_OFFSET(2)] AS g__2
) AS seeds
FROM yourTable
您可以使用CTE(如下所示)使用虚拟数据进行测试
#standardSQL
WITH yourTable AS (
SELECT
4500 AS port, 'This is an example' AS notes,
[STRUCT<seed INT64, guid STRING>
(12, 'eaf612'), (23, 'bea143'), (38, 'efk311')
] AS seeds
UNION ALL SELECT
4501 AS port, 'This is an example 2' AS notes,
[STRUCT<seed INT64, guid STRING>
(42, 'eaf412'), (53, 'bea153')
] AS seeds
)
SELECT
port, notes,
STRUCT(
seeds[SAFE_OFFSET(0)] AS g__0,
seeds[SAFE_OFFSET(1)] AS g__1,
seeds[SAFE_OFFSET(2)] AS g__2
) AS seeds
FROM yourTable
因此,从技术上讲,如果您知道种子数组中的项目/对象的最大数量 - 您可以手动编写所需的SQL语句,以便根据实际数据运行它。 希望你有个主意
当然你可以编写脚本/自动化过程 - 你可以在这里找到类似的旋转任务的例子:
https://stackoverflow.com/a/40766540/5221944
https://stackoverflow.com/a/42287566/5221944
答案 1 :(得分:1)
以下jq程序应该可以解决问题。至少它会为给定的JSON生成所需的结果。该计划是如此简短和直接,我会让它自己说话:
def array2object(prefix):
. as $in
| reduce range(0;length) as $i ({}; .["\(prefix)_\($i)"] = $in[$i]);
.seeds |= array2object("g__")