首页 > 解决方案 > 如何使用 jsonata 返回多个对象,分配第一个键/值,始终为 dateTime,其余键变化

问题描述

如何使用jsonata进行转换:

{
  "data": [
    {
      "dateTime": "2019-10-19T12:53:54.043Z",
      "Reactor3.Level": 1.51860072870498,
      "Reactor3.Temp": 27.1360543141452
    },
    {
      "dateTime": "2019-10-19T12:55:54.043Z",
      "Reactor3.Press": 88.9,
      "Reactor3.Temp": 24.1418981047159
    }
  ]
}

变成一系列只包含 {"dateTime":"2019-10-19T12:53:54.043Z", key[1]:value[1]},{"dateTime":"2019-10-19T12 两个键的对象:53:54.043Z",key[2]:value[2]} 如以下:

{
  "data": [
    {
      "dateTime": "2019-10-19T12:53:54.043Z",
      "Reactor3.Level": 1.51860072870498
    },
    {
      "dateTime": "2019-10-19T12:53:54.043Z",
      "Reactor3.Temp": 27.1360543141452
    },
    {
      "dateTime": "2019-10-19T12:55:54.043Z",
      "Reactor3.Press": 88.9
    },
    {
      "dateTime": "2019-10-19T12:55:54.043Z",
      "Reactor3.Temp": 24.1418981047159
    }
  ]
}

第一个键始终是 dateTime,其他键会有所不同,我想按 dateTime 分解所有其他键/值?这里的 Reactor3.Level、Reactor3.Temp、Reactor3.Press 只是会改变的示例。

编辑:在下面,我添加了我的问题的更通用版本。我本质上是在寻找一个 JSONata 查询来转换这个输入:

{
  "data": [
    {
      "TS": "TS1",
      "V1": 1,
      "V2": 2
    },
    {
      "TS": "TS2",
      "V2": 9,
      "V3": 8,
      "V4": 7
    }
  ]
}

其中键“TS”是每组中的第一个键,其他键会有所不同。并将其转换为以下输出:

{
  "data": [
    {
      "TS": "TS1",
      "V1": 1
    },
    {
      "TS": "TS1",
      "V2": 2
    },
    {
      "TS": "TS2",
      "V2": 9
    },
    {
      "TS": "TS2",
      "V3": 8
    },
    {
      "TS": "TS2",
      "V4": 7
    }
  ]
}

[已解决] SteveR 在下面解决了我的问题,我只想在此处添加一个 Node-RED “有效负载”友好版本的解决方案:链接:http ://try.jsonata.org/HJCjoHxoS

负载修改 JSONata:

payload.$ ~> | $ | { "data": data.(
    $obj := $;
    $key := "dateTime";
    $keys($obj)[$ != $key].{
        $key : $lookup($obj, $key),
        $: $lookup($obj, $)
    }
) } |

再次感谢@SteveR

标签: jsonata

解决方案


有趣的挑战,杰夫——但如果对象属性没有保证的顺序,它可能无法可靠地做到……它是否总是需要分布在其余属性上的“第一个”属性,或者你可以肯定地说它总是会被调用TS(使用您的简化示例)?

话虽如此,我确实找到了一个似乎有效的表达方式,尽管只是在我有限的测试中:

data.(
    $obj := $;
    $keys($obj)[[1..100]].(
        $key := $keys($obj)[0];
        {
            $key : $lookup($obj, $key),
            $: $lookup($obj, $)
        }
    )
)

本质上,对于每个传入的对象,获取它的键 - 对于索引在 1 - 100 之间的每个键(我知道,这是一个人为的限制),创建新对象{ key[0]: val[0], key[i]: val[i] }

如果您愿意,可以尝试在此处进行调整 => http://try.jsonata.org/ryh3hqM5H

如果您可以肯定地说第一个属性称为“TS”,我将使用该命名属性来简化表达式,如下所示:

data.(
    $obj := $;
    $key := "TS";
    $keys($obj)[$ != $key].{
        $key : $lookup($obj, $key),
        $: $lookup($obj, $)
    }
)

我确信有更好的方法来完成相同的转换,但我希望这会有所帮助......

祝你好运!

编辑:我看到我丢失了带有data属性的外部对象。您可以将它包装在我列出的表达式周围,或者如果需要维护其他属性,请使用对象转换语法仅修改该data属性:

$$ ~> | $ | { "data": data.(
    $obj := $;
    $key := "dateTime";
    $keys($obj)[$ != $key].{
        $key : $lookup($obj, $key),
        $: $lookup($obj, $)
    }
) } |

推荐阅读