The Challenges
I have Accounts retrieved from Salesforce like the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | [ { "LastModifiedDate" : "2015-12-09T21:29:01.000Z" , "Id" : "0016100000Kngh3AAB" , "type" : "Account" , "Name" : "AAA Inc." }, { "LastModifiedDate" : "2015-12-09T20:16:47.000Z" , "Id" : "0016100000KnXKhAAN" , "type" : "Account" , "Name" : "AAA Inc." }, { "LastModifiedDate" : "2015-12-12T02:06:48.000Z" , "Id" : "0016100000KqonvAAB" , "type" : "Account" , "Name" : "AAA Inc." }, ... ] |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | { "AAA Inc." : [ "0016100000Kngh3AAB" , "0016100000KnXKhAAN" , "0016100000KqonvAAB" , "0016100000KnggyAAB" , "0016100000KngflAAB" , "0016100000KqalVAAR" , "0016100000Kngh8AAB" , "0016100000KnVUKAA3" , "0016100000Kngh5AAB" , "0016100000KnVXdAAN" , "0016100000KnVh4AAF" , "0016100000KnVs6AAF" , "0016100000KnggAAAR" , "0016100000KnlokAAB" , "0016100000KnggKAAR" ], "Adam Smith" : [ "0016100000L7sDjAAJ" ], "Alice John Smith" : [ "0016100000L7x29AAB" ], "Alice Smith." : [ "0016100000L7sDiAAJ" ], ... |
Solutions
I device a two-stage solution. The first transform will create LinkedHashMap which will contain account name as key and the value as array of Account as shown below:1 2 3 4 5 | %dw 2.0 output application/java --- //payload groupBy $.Name orderBy $$ (payload groupBy (account) -> account.Name) orderBy (item, key) -> key |
1 2 3 4 5 6 | %dw 2.0 output application/java --- payload mapObject (item, key, index) -> { (key) : (item map (value) -> value.Id) } |
1 2 3 4 5 6 7 8 | %dw 2.0 output application/java --- //payload groupBy $.Name orderBy $$ ((payload groupBy (account) -> account.Name) orderBy (item, key) -> key) mapObject (item, key, index) -> { (key) : (item map (value) -> value.Id) } |
Key Learnings
The key concept of the above use case is to group the accounts with the same name and sort them in alphabetic order. The Mulesoft document about the groupBy and orderBy together with other core functions of dataweave can be found here The groupBy and orderBy have the similar signature:
1 2 3 4 | 1. groupBy(Array<t>, (item: T, index: Number) -> R): { (R): Array<t> } 2. groupBy({ (K)?: V }, (value: V, key: K) -> R): { (R): { (K)?: V } } 3. groupBy(Null, (Nothing, Nothing) -> Any): Null </t></t> |
1 2 3 | //payload groupBy $.Name //payload groupBy (account, index) -> account.Name payload groupBy (account) -> account.Name |
In my solution of the second stage, I use mapObject function as the following:
1 2 3 | payload mapObject (item, key, index) -> { (key) : (item map (value) -> value.Id) } |
In my work, I also need to remove the type attribute in the Account object.
1 2 3 4 5 6 7 8 9 | [ { "LastModifiedDate" : "2015-12-09T21:29:01.000Z" , "Id" : "0016100000Kngh3AAB" , "type" : "Account" , "Name" : "AAA Inc." }, ... ] |
1 2 3 | (payload orderBy (item) -> item.Name) map (account) -> { (account -- [ 'type' ]) } |
Summary
The key thinking of solve this kind of problem how to group, sort, and extract values from the Array or LinkedHashMap. Thus I have used the following core Dataweave functions:- groupBy
- orderBy
- map
- mapObject
If the payload is Array
- $ - item
- $$ - index
- $ - value
- $$ - key
- $$$ - index.
1 2 3 | (payload orderBy (item) -> item.Name) map (account, index) -> { (account -- [ 'type' ]) } |
1 2 3 | mapObject (item, key, index) -> { (key) : (item map (value) -> value.Id) } |
ReplyDeleteThank you for wonderful information
Mulesoft Online Training
Mulesoft Training in Hyderabad
Very informative post for mulesoft developers.You can also visit goformule.com for mulesoft stuff.
ReplyDelete