Как использовать 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", ключ [1]: значение [1]}, {"dateTime": "2019-10-19T12 : 53: 54.043Z ", ключ [2]: значение [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


person Jeff Tapia    schedule 26.10.2019    source источник


Ответы (1)


Интересная проблема, Джефф - но если свойства объекта не имеют гарантированного порядка, это может быть невозможно сделать надежно ... всегда ли это «первое» свойство, которое необходимо распределить по остальные из них, или вы можете точно сказать, что он всегда будет называться 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, $)
    }
) } |
person SteveR    schedule 27.10.2019
comment
Вау, это прекрасно работает, и я бы НИКОГДА не догадался об этом. Я все еще пытаюсь понять, как это работает. - person Jeff Tapia; 27.10.2019
comment
Согласен, читать сложно! В этом случае я бы сказал, что, вероятно, лучше использовать простую функцию JS для выполнения итераций и создания новых объектов - особенно для человека, который должен поддерживать эту логику в будущем ... - person SteveR; 27.10.2019
comment
Вот версия для полезной нагрузки Node RED: - person Jeff Tapia; 06.11.2019