Talend:将 JSON 行转换为列,从 JSON 中提取列名
Talend : Transform JSON lines to columns, extracting column names from JSON
我有一个 json 休息响应,其结构有点像这样:
{
"data" : [
{
"fields" : [
{ "label" : "John", "value" : "John" },
{ "label" : "Smith", "value" : "/person/4315" },
{ "label" : "43", "value" : "43" },
{ "label" : "London", "value" : "/city/54" }
]
},
{
"fields" : [
{ "label" : "Albert", "value" : "Albert" },
{ "label" : "Einstein", "value" : "/person/154" },
{ "label" : "141", "value" : "141" },
{ "label" : "Princeton", "value" : "/city/9541" }
]
}
],
"columns" : ["firstname", "lastname", "age", "city"]
}
我正在寻找一种方法将此数据转换为
这样的行
| first_name_label | firstname_value | lastname_label | lastname_value | age_label | age_value | city_label | city_value |
---------------------------------------------------------------------------------------------------------------------------
| John | John | Smith | /person/4315 | 43 | 43 | London | /city/54 |
| Albert | Albert | Einstein | /person/154 | 141 | 141 | Princeton | /city/9541 |
当然,列数和它们的名称可能会改变,所以我不知道运行前的架构。
我可能可以写 java 来处理这个问题,但我想知道是否有更标准的方法。
我是 Talend 的新手,所以我花了几个小时尝试,但由于我的尝试可能完全错误,所以我不会在这里描述它。
感谢您的帮助。
这是我整理的完全动态的解决方案。
首先,您需要阅读 json 以获得列列表。这是 tExtractJSONFields_2 的样子:
然后将列及其位置存储在 tHashOutput 中(您需要在文件 > 项目属性 > 设计器 > 调色板设置中取消隐藏)。在 tMap_2 中,您使用序列获取列的位置:
Numeric.sequence("s", 1, 1)
这个子作业的输出是:
|=-------+--------=|
|position|column |
|=-------+--------=|
|1 |firstname|
|2 |lastname |
|3 |age |
|4 |city |
'--------+---------'
第二步是再次读取json,以解析字段属性。
与步骤 1 一样,您需要为每个字段添加一个相对于列的位置。这是我用来获取序列的表达式:
(Numeric.sequence("s1", 0, 1) % ((Integer)globalMap.get("tHashOutput_1_NB_LINE"))) + 1
请注意,我使用了不同的序列名称,因为序列在整个作业中保持其值。我使用 tHashOutput_1 中的列数来保持动态。
这是此子作业的输出:
|=-------+---------+---------------=|
|position|label |value |
|=-------+---------+---------------=|
|1 |John |John |
|2 |Smith |/person/4315 |
|3 |43 |43 |
|4 |London |/city/54 |
|1 |Albert |Albert |
|2 |Einstein |/person/154 |
|3 |141 |141 |
|4 |Princeton|/city/9541 |
'--------+---------+----------------'
在最后一个子作业中,您需要使用我们存储的列位置将字段数据与列连接起来。
在 tSplitRow_1 中,我为每个传入行生成 2 行。每行都是一个键值对。第一行是 <columnName>_label
(如 firstname_label、lastname_label),它的值是来自字段的标签。第 2 行的键是 <columnName>_value
,它的值是来自字段的值。
再次,我们需要在 tMap_4 中添加一个位置到我们的数据中,使用这个表达式:
(Numeric.sequence("s2", 0, 1) / ((Integer)globalMap.get("tHashOutput_1_NB_LINE") * 2)) + 1
请注意,由于 tSplitRow 中的行数是原来的两倍,因此我将列数乘以 2。
这将为需要位于输出文件中同一行的数据分配相同的 ID。
此 tMap 的输出将类似于:
|=-+---------------+-----------=|
|id|col_label |col_value |
|=-+---------------+-----------=|
|1 |firstname_label|John |
|1 |firstname_value|John |
|1 |lastname_label |Smith |
|1 |lastname_value |/person/4315|
|1 |age_label |43 |
|1 |age_value |43 |
|1 |city_label |London |
|1 |city_value |/city/54 |
|2 |firstname_label|Albert |
|2 |firstname_value|Albert |
|2 |lastname_label |Einstein |
|2 |lastname_value |/person/154 |
|2 |age_label |141 |
|2 |age_value |141 |
|2 |city_label |Princeton |
|2 |city_value |/city/9541 |
'--+---------------+------------'
这将我们带到最后一个组件 tPivotToColumnsDelimited,它将使用唯一 ID 将我们的行转换为列。
最终结果是一个 csv 文件,如:
id;firstname_label;firstname_value;lastname_label;lastname_value;age_label;age_value;city_label;city_value
1;John;John;Smith;/person/4315;43;43;London;/city/54
2;Albert;Albert;Einstein;/person/154;141;141;Princeton;/city/9541
请注意,您最终在开头有一个无关的列,它是行 ID,可以通过读取文件并删除它来轻松删除它。
我尝试在输入 json 中添加一个新列以及相应的字段,它按预期工作。
我有一个 json 休息响应,其结构有点像这样:
{
"data" : [
{
"fields" : [
{ "label" : "John", "value" : "John" },
{ "label" : "Smith", "value" : "/person/4315" },
{ "label" : "43", "value" : "43" },
{ "label" : "London", "value" : "/city/54" }
]
},
{
"fields" : [
{ "label" : "Albert", "value" : "Albert" },
{ "label" : "Einstein", "value" : "/person/154" },
{ "label" : "141", "value" : "141" },
{ "label" : "Princeton", "value" : "/city/9541" }
]
}
],
"columns" : ["firstname", "lastname", "age", "city"]
}
我正在寻找一种方法将此数据转换为
这样的行| first_name_label | firstname_value | lastname_label | lastname_value | age_label | age_value | city_label | city_value |
---------------------------------------------------------------------------------------------------------------------------
| John | John | Smith | /person/4315 | 43 | 43 | London | /city/54 |
| Albert | Albert | Einstein | /person/154 | 141 | 141 | Princeton | /city/9541 |
当然,列数和它们的名称可能会改变,所以我不知道运行前的架构。 我可能可以写 java 来处理这个问题,但我想知道是否有更标准的方法。
我是 Talend 的新手,所以我花了几个小时尝试,但由于我的尝试可能完全错误,所以我不会在这里描述它。
感谢您的帮助。
这是我整理的完全动态的解决方案。
首先,您需要阅读 json 以获得列列表。这是 tExtractJSONFields_2 的样子:
然后将列及其位置存储在 tHashOutput 中(您需要在文件 > 项目属性 > 设计器 > 调色板设置中取消隐藏)。在 tMap_2 中,您使用序列获取列的位置:
Numeric.sequence("s", 1, 1)
这个子作业的输出是:
|=-------+--------=|
|position|column |
|=-------+--------=|
|1 |firstname|
|2 |lastname |
|3 |age |
|4 |city |
'--------+---------'
第二步是再次读取json,以解析字段属性。
(Numeric.sequence("s1", 0, 1) % ((Integer)globalMap.get("tHashOutput_1_NB_LINE"))) + 1
请注意,我使用了不同的序列名称,因为序列在整个作业中保持其值。我使用 tHashOutput_1 中的列数来保持动态。
这是此子作业的输出:
|=-------+---------+---------------=|
|position|label |value |
|=-------+---------+---------------=|
|1 |John |John |
|2 |Smith |/person/4315 |
|3 |43 |43 |
|4 |London |/city/54 |
|1 |Albert |Albert |
|2 |Einstein |/person/154 |
|3 |141 |141 |
|4 |Princeton|/city/9541 |
'--------+---------+----------------'
在最后一个子作业中,您需要使用我们存储的列位置将字段数据与列连接起来。
在 tSplitRow_1 中,我为每个传入行生成 2 行。每行都是一个键值对。第一行是 <columnName>_label
(如 firstname_label、lastname_label),它的值是来自字段的标签。第 2 行的键是 <columnName>_value
,它的值是来自字段的值。
再次,我们需要在 tMap_4 中添加一个位置到我们的数据中,使用这个表达式:
(Numeric.sequence("s2", 0, 1) / ((Integer)globalMap.get("tHashOutput_1_NB_LINE") * 2)) + 1
请注意,由于 tSplitRow 中的行数是原来的两倍,因此我将列数乘以 2。
这将为需要位于输出文件中同一行的数据分配相同的 ID。
此 tMap 的输出将类似于:
|=-+---------------+-----------=|
|id|col_label |col_value |
|=-+---------------+-----------=|
|1 |firstname_label|John |
|1 |firstname_value|John |
|1 |lastname_label |Smith |
|1 |lastname_value |/person/4315|
|1 |age_label |43 |
|1 |age_value |43 |
|1 |city_label |London |
|1 |city_value |/city/54 |
|2 |firstname_label|Albert |
|2 |firstname_value|Albert |
|2 |lastname_label |Einstein |
|2 |lastname_value |/person/154 |
|2 |age_label |141 |
|2 |age_value |141 |
|2 |city_label |Princeton |
|2 |city_value |/city/9541 |
'--+---------------+------------'
这将我们带到最后一个组件 tPivotToColumnsDelimited,它将使用唯一 ID 将我们的行转换为列。
最终结果是一个 csv 文件,如:
id;firstname_label;firstname_value;lastname_label;lastname_value;age_label;age_value;city_label;city_value
1;John;John;Smith;/person/4315;43;43;London;/city/54
2;Albert;Albert;Einstein;/person/154;141;141;Princeton;/city/9541
请注意,您最终在开头有一个无关的列,它是行 ID,可以通过读取文件并删除它来轻松删除它。
我尝试在输入 json 中添加一个新列以及相应的字段,它按预期工作。