使用 Dataweave2.0 提取内部字段对象并将它们应用于相应的顶级对象

Extract the inner field objects and apply them to respective top level objects using Dataweave2.0

我正在尝试从给定的输入中获得以下输出。我已经尝试了几种制作通用函数的方法,这样当任何数据以相似的结构传递时,我都会得到相似的输出。请帮我实现这个目标。

输入

[{
  "name": "Thinker",
  "details": [
      {
      "num": 1
      }, 
      {
      "num": 2
      }
   ]
}, 
{
  "name": "Blinker",
  "details": [
      {
      "num": 3
      }, 
      {
      "num": 4
      }
   ]
}]

输出

[{
  "name": "Thinker",
  "num": 1
},
{
  "name": "Thinker",
  "num": 2
},
{
  "name": "Blinker",
  "num": 3
},
{
  "name": "Blinker",
  "num": 4
}]

试试这个数据仓库

第一个映射到主阵列上的映射

第 2 张地图详细信息

reduce 将嵌套数组转换为单个数组

%dw 2.0
output application/json
---
payload map(
    ($.details map(item,index)->{
        "name":($.name),
        "num":item[0]
    })
)reduce($$++$)

输出

[
  {
    "name": "Thinker",
    "num": 1
  },
  {
    "name": "Thinker",
    "num": 2
  },
  {
    "name": "Blinker",
    "num": 3
  },
  {
    "name": "Blinker",
    "num": 4
  }
]

DW

%dw 2.0
output application/json
---
payload map(
    ($.details map(item,index)->{
        (keysOf($)[0]):($.name),
        (keysOf(item)[0]):item[0]
    })
)reduce($$++$)

关键是通过外部和内部数组进行映射,然后将结果展平:

output application/json
---
flatten (payload map ((item, index) -> item.details map ((detail, index) -> {
    name: item.name,
    num: detail.num
})))

正如 Aled 在他对其中一个答案的评论中提到的,这可能是解决此问题的另一种方法。

%dw 2.0
output application/json
---
payload flatMap (item,index) -> (
      item.details map {
           name: item.name,
           num:  $.num
      }
)

如果您的请求结构将始终保持这种方式(无论字段名称如何),那么您可以尝试下面的脚本,它更通用并且适用于相同类型的结构

%dw 2.0
output application/json
---
payload flatMap ((item, index) -> 
   (item filterObject ($ is Array))[0] map 
                 ($ ++ (item filterObject ($ is String | Number | Null)) )
 
)

注意:它总是可以在这种类型的结构上工作,而不依赖于字段名称,并给出预期的输出

[{
  "anyname": "xyz",
  "anydetails": [
      {
      "abc": 1
      }, 
      {
      "ijk": 2
      }
   ]
}]