DevTC
DevTC

Reputation: 3

MuleSoft DataWeave to roll up joined query results

I have returned some data from a database call which joins several tables together. The current payload looks something like this:

[
 { "ID": 11111
 , "Ref": "123ABC"
 , "Year": 1994
 , "Title": "A title"
 , "Author": "Joe Bloggs"
 },
 { "ID": 11111
 , "Ref": "123ABC"
 , "Year": 1994
 , "Title": "A title"
 , "Author": "John Smith"
 },
 { "ID": 22222
 , "Ref": "456DEF"
 , "Year": 2018
 , "Title": "Another title"
 , "Author": "Lucy Jones"
 }
]

Can anyone help with the DataWeave required to translate it to this:

[
 { "ID": 11111
 , "Ref": "123ABC"
 , "Year": 1994
 , "Title": "A title"
 , "Authors": [ {"Name": "Joe Bloggs"}, {"Name": "John Smith"} ]
 },
 { "ID": 22222
 , "Ref": "456DEF"
 , "Year": 2018
 , "Title": "Another title"
 , "Authors": [ {"Name": "Lucy Jones"} ]
 }
]

I've tried playing around with distinctBy and filter, but have only managed to get this so far:

%dw 2.0
output application/json
var myVar = payload distinctBy () -> 
   { ID: $.ID
   , Ref: $.Ref
   , Year: $.Year
   , Title: $.Title
   } 
---
myVar map () -> using (thisID = myVar.ID)
   { ID: $.ID
   , Ref: $.Ref
   , Year: $.Year
   , Title: $.Title
   , Authors: payload map {Name: $.Author} 
   //, Authors: payload filter ($.*ID contains thisID) map {Name: $.Author}
   }

Result:

[
  {
    "ID": 11111,
    "Ref": "123ABC",
    "Year": 1994,
    "Title": "A title",
    "Authors": [
      {
        "Name": "Joe Bloggs"
      },
      {
        "Name": "John Smith"
      },
      {
        "Name": "Lucy Jones"
      }
    ]
  },
  {
    "ID": 22222,
    "Ref": "456DEF",
    "Year": 2018,
    "Title": "Another title",
    "Authors": [
      {
        "Name": "Joe Bloggs"
      },
      {
        "Name": "John Smith"
      },
      {
        "Name": "Lucy Jones"
      }
    ]
  }
]

Upvotes: 0

Views: 88

Answers (1)

Harshank Bansal
Harshank Bansal

Reputation: 3261

Assuming fields other than the Author will be same for a particular ID, you can use groupBy to make groups for each ID. Then map the grouped values by updating the Author to be equal to the combined value of all the Author in the group.

%dw 2.0
output application/json
---
payload groupBy $.ID
    pluck ((groupedValues) -> {
        (groupedValues[0] - "Author"),
        Author: groupedValues map {Name: $.Author}
    })

Also note that using keyword is deprecated in Mule 4, so avoid using it. You should instead use the do block for it

Upvotes: 1

Related Questions