我有一个具有这种扁平结构的JSON:
[{
"PK": "1111",
"SOURCE_DB": "Oracle",
"CONTACT_TYPE": "Phone",
"CONTACT_SUBTYPE": "Work",
"EMAIL": null
"PHONE_COUNTRY_CODE": "44",
"PHONE_NUMBER": "12345678",
"PHONE_EXT": "907643",
"STATUS": "Active"
}, {
"PK": "1111",
"SOURCE_DB": "Oracle",
"CONTACT_TYPE": "Phone",
"CONTACT_SUBTYPE": "Home",
"EMAIL": null
"PHONE_COUNTRY_CODE": "353",
"PHONE_NUMBER": "87654321",
"PHONE_EXT": null,
"STATUS": "Active"
}, {
"PK": "1111",
"SOURCE_DB": "",
"CONTACT_TYPE": "Email",
"CONTACT_SUBTYPE": "Personal",
"EMAIL": "me@mail.com"
"PHONE_COUNTRY_CODE": null,
"PHONE_NUMBER": null,
"PHONE_EXT": null,
"STATUS": "Active"
},
{
"PK": "2222",
"SOURCE_DB": "DB2",
"CONTACT_TYPE": "Phone",
"CONTACT_SUBTYPE": "Home",
"EMAIL": null
"PHONE_COUNTRY_CODE": "44",
"PHONE_NUMBER": "98761234",
"PHONE_EXT": null,
"STATUS": "Inactive"
}, {
"PK": "2222",
"SOURCE_DB": "DB2",
"CONTACT_TYPE": "Email",
"CONTACT_SUBTYPE": "Work",
"EMAIL": "you@mail.co.uk"
"PHONE_COUNTRY_CODE": null,
"PHONE_NUMBER": null,
"PHONE_EXT": null,
"STATUS": "Active"
}
]
然后,我想首先按键(PK)对它们进行分组,然后在每个条目中将ContactMethods组合在一起。这是输出:
{
"Accounts": [{
"Reference": {
"Key": "1111",
"System": "Oracle"
},
"ContactMethods": {
"Phone": [{
"Subtype": "Work",
"CountryCode": "44",
"Number": "12345678",
"Extension": "907643",
"Active": true
}, {
"Subtype": "Home",
"CountryCode": "353",
"Number": "87654321",
"Extension": null,
"Active": true
}
],
"Email": [{
"Subtype": "Personal",
"EmailAddress": "my@mail.com",
"Active": true
}
]
}
}, {
"Reference": {
"Key": "2222",
"System": "DB2"
},
"ContactMethods": {
"Phone": [{
"Subtype": "Home",
"CountryCode": "44",
"Number": "98761234",
"Extension": null,
"Active": false
}
],
"Email": [{
"Subtype": "Work",
"EmailAddress": "you@mail.co.uk",
"Active": true
}
]
}
}
]
}
我能够通过PK对此进行分组,但是我在第二部分遇到了困难,关于如何在嵌套结构中进行分组。你能展示样品规格并做一些解释吗?
答案 0 :(得分:1)
可能但真的很复杂/冗长。这推动了Jolt应该做的事情的界限。
一个支点和一些重新映射是可维护的,但这很复杂,如果出现问题/数据很奇怪,将很难调试。
需要5个步骤。两个将STATUS从字符串修复为布尔值。两个用于透视和子透视数据。最后一个把所有东西放在正确的最后位置。
我建议检查每个步骤,检查它自己的Jolt演示站点的选项卡/副本中的每个步骤,以查看/了解每个步骤正在做什么。
规格
[
{
// ninja in a true and false value so that
// Status "Active" / "Inactive" can be "mapped" to booleans
"operation": "default",
"spec": {
"*": {
"FALSE": false,
"TRUE": true
}
}
},
{
// fix STATUS
"operation": "shift",
"spec": {
"*": {
//
"STATUS": {
// Match "Active" as make STATUS be true
"Active": {
"@(2,TRUE)": "[&3].STATUS"
},
// Everything else set to false
"*": {
"@(2,FALSE)": "[&3].STATUS"
}
},
// match and discard TRUE and FALSE
"TRUE|FALSE": null,
// pass everything else thru
"*": "[&1].&"
}
}
},
{
// now, group by PK value
"operation": "shift",
"spec": {
// top level array
"*": {
"PK": {
"*": { // match any value of PK
// go back up and grab the whole block and write
// it to the ouput where the key, is the value of PK
"@2": "&1[]"
}
}
}
}
},
{
// sub group by CONTACT_TYPE, with the complication of
// pulling one entry off to serve as the "Reference"
"operation": "shift",
"spec": {
"*": { // pk value
"0": { // special case the Zeroth item so that
// we can pull off once copy to serve as the
// Reference
"@": "&2.Reference",
// sub group by CONTACT_TYPE
"CONTACT_TYPE": {
"*": {
"@2": "&4.ContactMethods.&1[]"
}
}
},
"*": { // all the rest of the array indicies
// sub group by CONTACT_TYPE
"CONTACT_TYPE": {
"*": {
"@2": "&4.ContactMethods.&1[]"
}
}
}
}
}
},
{
// Data fixing and Grouping done, now put everything
// in its final place
"operation": "shift",
"spec": {
"*": { // top level pk
"Reference": {
"PK": "Accounts[#3].Reference.Key",
"SOURCE_DB": "Accounts[#3].Reference.System"
},
"ContactMethods": {
"Phone": {
"*": {
"CONTACT_SUBTYPE": "Accounts[#5].ContactMethods.Phone[&1].Subtype",
"PHONE_COUNTRY_CODE": "Accounts[#5].ContactMethods.Phone[&1].CountryCode",
"PHONE_NUMBER": "Accounts[#5].ContactMethods.Phone[&1].Number",
"PHONE_EXT": "Accounts[#5].ContactMethods.Phone[&1].Extension",
"STATUS": "Accounts[#5].ContactMethods.Phone[&1].Active"
}
},
"Email": {
"*": {
"CONTACT_SUBTYPE": "Accounts[#5].ContactMethods.Email[&1].Subtype",
"EMAIL": "Accounts[#5].ContactMethods.Email[&1].EmailAddress",
"STATUS": "Accounts[#5].ContactMethods.Email[&1].Active"
}
}
}
}
}
}
]