Dataweave :需要从有效负载中获取所需的输出

Dataweave : Need to get the desired output from the payload

我是 MuleSoft 的新手,正在为 Data Weave 的场景苦苦挣扎。有人可以帮我优化一下从输入负载中获得所需输出的方法吗:

输入:

[
  {
    "uniqueID": "1",
    "Base Rate": "0.15",
    "result": "success"
  },
  {
    "uniqueID": "1",
    "Base Rate": {
      "value": "0.15",
      "errorMessage": "Base Rate - Must be between 10 and 100"
    },
    "result": "failure"
  },
  {
    "uniqueID": "1",
    "Base Rate": {
      "value": "0.15",
      "errorMessage": "Base Rate - Cannot be a decimal"
    },
    "result": "failure"
  },
{
    "uniqueID": "1",
    "Number of Buildings": {
      "value": "1",
      "errorMessage": "Invalid Number of Buildings - Gross Area is greater than zero"
    },
    "result": "failure"
  },
   {
    "uniqueID": "2",
    "Closing Cost": {
      "value": "-1500",
      "errorMessage": "Closing Cost Cannot be negative"
    },
    "result": "failure"
  },
{
    "uniqueID": "3",
    "Base Rate Tenor": {
      "value": "",
      "errorMessage": "Base Rate Tenor - Invalid Value"
    },
    "result": "failure"
  }
]

Base Rate、Closing Cost等字段只是示例,可以是任何字段名称;对象的数量也可以变化。 我们只需要考虑那些结果为 'failure' 的对象。同一字段可以有多个错误消息,例如在输入中有 2 个不同的对象和 'Base Rate' 的错误消息。我们需要使用管道运算符将相同字段名称和相同唯一 ID 的错误消息组合在一起。因此,预期输出如下:

{
    "errors":[
            {
              "uniqueId" : "1",
              "Base Rate": "BaseRate Must be between 10 and 100 | Base Rate - Cannot be a decimal"  ,
              "Number of Buildings": "Invalid Number of Buildings - Gross Area is greater than zero"
            },
            {
              "uniqueId" : "2",
              "Closing Cost": "Closing Cost Cannot be negative"         
            },
            {
              "uniqueId" : "3",
              "Base Rate Tenor": "Base Rate Tenor - Invalid Value"         
            }
        ]

请试试这个

%dw 2.0
output application/json

fun getErrorMessage (obj)= (
    obj  mapObject (        
        (($$): $.errorMessage) if ($ is Object and (not isEmpty($.errorMessage)))
    )
)

fun formatFinalObject (obj) = (
    obj groupBy ($$) 
        mapObject ((value, key) -> 
            (key): value.*"$(key)" joinBy " | "
        )
)
---
{
    errors: payload groupBy ($.result ++ "-" ++ $.uniqueID) 
        filterObject ($$ startsWith "failure") pluck ((value, key) -> 
        {
            uniqueId: value[0].uniqueID,        
        } ++ (
                formatFinalObject (
                    value reduce ((item, acc={}) -> 
                        acc ++ (getErrorMessage(item))
                ))          
            )        
    )
}

因为嵌套,有点复杂。我必须分组,然后映射并采摘以获取预期格式的值。您可以像我在一个案例中所做的那样,通过将部分逻辑提取到函数中来降低复杂性。

%dw 2.0
output application/json
fun groupErrors(o)=o mapObject ($$): $.value joinBy  " | " 
---
{
    errors: (payload filter $.result == "failure")
        groupBy ((item, index) -> item.uniqueID)
        mapObject ((value, key, index) -> 
            (key): value 
                        map (($ - "uniqueID" - "result")
                            mapObject { id: $$, value: $.errorMessage}    
                        )
        )
        pluck ((value, key, index) -> { uniqueID: key, (groupErrors(value groupBy $.id))})
}