Mulesoft Dataweave:展平 JSON 以创建数据库记录

问题描述 投票:0回答:1

我使用 Mulesoft 4、Dataweave 2.3。 我想展平 JSON 对象。 JSON 中的每个键都应该位于新记录对象的键中。当 JSON 具有嵌套对象/数组时,键将用“.”连接。 因此准备将其作为记录插入到数据库表中,而不会丢失原始 JSON 的键名。 这是我传入的 JSON 消息:

{
  "supplierId": "123456",
  "targets": {
    "test": "JustAtest"
  },
  "assets": [
    {
      "id": "1229782",
      "serialNumber": "120007324",
      "name": "Machine A",
      "gpsPostition": {
        "longitude": 12.234,
        "Latitude": 45.12
      },
      "used": [
        {
          "startTime": "2023-12-12T08:08:00.345Z",
          "KWH": 234
        },
        {
          "startTime": "2023-12-13T08:08:00.372Z",
          "KWH": 240
        }
      ]
    },
    {
      "id": "1229781",
      "serialNumber": "120007323",
      "name": "Machine B1",
      "gpsPostition": {
        "longitude": 18.229,
        "Latitude": 123.487
      },
      "used": [
        {
          "startTime": "2023-12-14T10:15:00.231Z",
          "KWH": "220"
        },
        {
          "startTime": "2023-12-15T10:15:00.117Z",
          "KWH": "154"
        }
      ]
    }
  ]
}

这应该是结果:

var ExpectedResult = [
    {"supplierId." : "123456"},
    {"targets.test." : "JustAtest"},
    {"assets.id." : "1229782"},
    {"assets.serialNumber." : "120007324"},
    {"assets.name.": "Machine A"},
    {"assets.gpsPostion.longitude.": 12.234},
    {"assets.gpsPostion.latitude.": 45.12},
    {"assets.used.startTime.": "2023-12-12T08:08:00.345Z"},
    {"assets.used.KWH.": 234},
    {"assets.used.startTime.": "2023-12-13T08:08:00.372Z"},
    {"assets.used.KWH.": 240},
    {"assets.id." : "1229781"},
    {"assets.serialNumber." : "120007323"},
    {"assets.name.": "Machine B1"},
    {"assets.gpsPostion.longitude.": 18.229},
    {"assets.gpsPostion.latitude.": 123.487},
    {"assets.used.startTime.": "2023-12-14T10:15:00.231Z"},
    {"assets.used.KWH.": 220},
    {"assets.used.startTime.": "2023-12-15T10:15:00.117Z"},
    {"assets.used.KWH.": 154}
]

这是我尝试过的:

fun testMe(mesg1: Any, prefix, newRecords: Any) = do {
    fun createDbsRecord(mesg: Any, prefix) = do {
    var pre = if(prefix == null) "" else prefix ++ "."
    ---
    mesg  match {
        case mesg is Object -> mesg mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key)))
        case [x ~ xs] -> mesg map ($ mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key))))
        //case mesg is Array -> mesg map ($ mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ key)))
        else -> (newRecords << {(pre): (mesg)}) 
        }
    }
    ---
    createDbsRecord(mesg1, null)    
}

output application/json
---
//mesg is the incoming JSON message
testMe(mesg, null, [])

这是我收到的错误:

''' 无法将 Array ([{"supplierId.": "123456"}]) 强制转换为 Object

120| case mesg 是 Object -> mesg mapObject((value,key,index) -> createDbsRecord(value, (pre) ++ (key))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ '''

我在调试中注意到 newRecords 数组似乎没有填充新对象(记录)。而且 mesg1 数组也没有被破坏。对象不会被移除。

json function dataweave mulesoft
1个回答
0
投票

采用这个问题的优秀方法,你可以获得预期的结果。我必须添加对数组的支持并删除它们的索引(假设所有数字键都是索引)。默认情况下,我没有在按键末尾添加点。您可以取消注释一行来获取它。

%dw 2.0
import * from dw::util::Tree
import isNumeric from dw::core::Strings

fun collectLeaves(data) =
  if ((data is Object) == false)
    data
  else
    data mapObject ((value, key, index) -> value match {
        case value is Object -> collectLeaves(value)
        case value is Array -> value reduce ((item, accumulator = {}) -> accumulator ++ collectLeaves(item))
        else -> 
          (key): value

      })

fun objToProperties(obj) =
  (obj pluck ((value, key, index) -> 
    (key): value
  ))
var aggregatedKeys = payload mapLeafValues (value, path) -> {
  (path.selector 
    filter (!isNumeric($)) // removed array indexes
    joinBy "." 
    // ++ "." // uncomment if you want a dot at the end of the key
  ):
  value
}
output application/json  
---
collectLeaves(aggregatedKeys)

输出:

{
  "supplierId": "123456",
  "targets.test": "JustAtest",
  "assets.id": "1229782",
  "assets.serialNumber": "120007324",
  "assets.name": "Machine A",
  "assets.gpsPostition.longitude": 12.234,
  "assets.gpsPostition.Latitude": 45.12,
  "assets.used.startTime": "2023-12-12T08:08:00.345Z",
  "assets.used.KWH": 234,
  "assets.used.startTime": "2023-12-13T08:08:00.372Z",
  "assets.used.KWH": 240,
  "assets.id": "1229781",
  "assets.serialNumber": "120007323",
  "assets.name": "Machine B1",
  "assets.gpsPostition.longitude": 18.229,
  "assets.gpsPostition.Latitude": 123.487,
  "assets.used.startTime": "2023-12-14T10:15:00.231Z",
  "assets.used.KWH": "220",
  "assets.used.startTime": "2023-12-15T10:15:00.117Z",
  "assets.used.KWH": "154"
}
© www.soinside.com 2019 - 2024. All rights reserved.