当等价做和不匹配时改进左连接嵌套映射对象

improve leftJoin nested mapObject when equivalence do and do not match

我正在使用以下 dataweave 函数,它确实有效。

%dw 2.0
import * from dw::core::Arrays
output application/json

var mysqlInvoices = [
    {
        "id": 1,
        "owner": "Joseph"
    },
    {
        "id": 2,
        "owner": "Maria"
    }
]

var sapInvoices = [
    {
        "number": 3,
        "issuedBy": "XYZ"
    },
    {
        "number": 4,
        "issuedBy": "ABC"
    }
]
---
leftJoin(mysqlInvoices, sapInvoices, (m) -> m.id, (s) -> s.number) map (item, index) -> 
  (item.l mapObject (sItem, sKey) -> 
        (if ((sKey) as String == "id") "identifier" 
        else if ((sKey) as String == "owner") "ownerName" 
        else (sKey)): sItem)
  ++ 
  (if (item.r != null) 
    item.r mapObject (sItem, sKey) -> 
        (sKey): sItem
  else 
    sapInvoices[0] mapObject 
        (sItem, sKey) -> (sKey): "") 

不过,我在想能不能在两点上改进这个功能:

  1. 更改关键条件:

我认为检查每个键是否匹配 if 条件以更改它不是最佳做法:

(if ((sKey) as String == "id") "identifier" 
else if ((sKey) as String == "owner") "ownerName" 
else (sKey)): sItem
  1. leftJoin不匹配键时,使用原始对象将其映射为空字符串:
sapInvoices[0] mapObject (sItem, sKey) -> 
(sKey): ""

我对这两点感到不舒服,我相信有改进这段代码的方法,我只是不知道如何。

如果有不同的方法来完成相同的任务,我也很感激这种建议。

试试下面的代码,如果有的话,代码似乎更简单一些:

%dw 2.0
import * from dw::core::Arrays
output application/json

var mysqlInvoices = [
    {
        "id": 1,
        "owner": "Joseph"
    },
    {
        "id": 2,
        "owner": "Maria"
    }
]

var sapInvoices = [
    {
        "number": 3,
        "issuedBy": "XYZ"
    },
    {
        "number": 4,
        "issuedBy": "ABC"
    }
]

var fs2rn = {
    id: "identifier",
    owner: "ownerName"
}

var rightEmpty= {number:"",issuedBy:""}
---
leftJoin(
    // Do the field renaming at the very begining
    mysqlInvoices map ($ mapObject {(fs2rn[$$] default $$): $}), 
    sapInvoices, 
    (m) -> m.identifier, 
    (s) -> s.number
)
// Iterate over the results
// Get just the values, and colapse the objects into a single object
map (
    {($ pluck $)}
)
// Iterate over the results and use pattern-matching to 
// 
map (
    $ match {
        // Check if you have an id but not a number fields
        // In which case add the rightEmpty object
        case o if (o.identifier? and not (o.number?)) -> o ++ rightEmpty
        // Or give the object because you now have both an id and a number
        else o -> o
    }
)

我用到的特性和功能是:

如果我要给你一个建议,那就是更好地缩进你的代码。尽管如此,还是很不错的!

根据George的回答,可以去掉pluck和match,直接合并left和righttable。见下文:

%dw 2.0
import * from dw::core::Arrays
output application/json

var mysqlInvoices = [
    {
        "id": 1,
        "owner": "Joseph"
    },
    {
        "id": 2,
        "owner": "Maria"
    }
]

var sapInvoices = [
    {
        "number": 3,
        "issuedBy": "XYZ"
    },
    {
        "number": 4,
        "issuedBy": "ABC"
    }
]

var fs2rn = {
    id: "identifier",
    owner: "ownerName"
}

var rightEmpty= {number:"",issuedBy:""}
---
leftJoin(
    // Do the field renaming at the very begining
    mysqlInvoices map ($ mapObject {(fs2rn[$$] default $$): $}), 
    sapInvoices, 
    (m) -> m.identifier, 
    (s) -> s.number
) map (item) -> item.l ++ (item.r default rightEmpty)