Как я могу создать гибкую структуру JSON в Node Red? - PullRequest
0 голосов
/ 30 января 2019

Предположим, у меня есть следующий CSV:

A_Key;B_Key;C_Key;...;X_Key
Value 1;2;Value 1.3;...;Value 1.24
Value 1;;Value 2.3;...;Value 2.24
...

Я уже создал шаблон Node Red, который позволяет мне извлечь некоторые пары ключ-значение для создания простого вывода JSON.Тем не менее, это отношения один на один, но мне нужно более гибкое решение.Существуют определенные требования к объектам, которые должны выводить:

  1. Все строки имеют один столбец, который служит первичным ключом - предположим, что это столбец «Ключ C». Этот первичный ключ должен находиться вПолученный Объект.Второй столбец «Ключ» в нашем примере содержит тип объекта.Он постоянен и поэтому игнорируется.
  2. Из оставшихся столбцов есть определенный список, который является обязательным для загрузки, но некоторые поля могут быть пустыми (в этом случае значение NULL должно быть значением).Эти поля перечислены в подобъекте под названием «Свойства»
  3. Может случиться, что в CSV отсутствует полный столбец.Если это обязательный столбец, все объекты должны иметь ключ, хотя и со значением NULL.
  4. Может случиться, что у CSV есть дополнительные столбцы, которых нет в обязательном списке.Эти необязательные атрибуты должны появляться в подобъекте «всеохватывающего», называемом «Extras».

Полученный объект из CSV выше может выглядеть так:

[
    {
        "A_Key": "Value 1",
        "C_Key": "Value 1.3",
        "Properties": {
            "B_Key": "2",
            "F_Key": ...,
            ...
            "X_Key": "Value 1.24"
        },
        "Extras": {
           "D_Key": ...,
           "E_Key": ...,
           ...
        }
    },
    {
        "A_Key": "Value 1",
        "C_Key": "Value 2.3",
        "Properties": {
            "B_Key": "NULL",
            "F_Key": ...,
            ...
            "X_Key": "Value 2.24"
        },
        "Extras": {
           "D_Key": ...,
           ...
        }
    },
]

Я хотел бы сделать следующее: Я хотел бы создать узел функции «Подготовить JSON» в Node Red, который перебирает столбцы CSV и использует заголовки столбцов в качестве ключей для получающегося JSON.Я уже подготовил функцию в начале потока, которая устанавливает необходимые переменные:

var primaryKey = "C_Key";
var mandatoryPart = "Properties";
var mandatoryKeys = ["B_Key",
"F_Key",
...
"X_Key"];
var optionalPart = "Extras";
var appendOptionalPart = true;

msg.primaryKey = primaryKey;
msg.mandatoryPart = mandatoryPart
msg.mandatoryKeys = mandatoryKeys;
msg.optionalPart = optionalPart;
msg.appendOptionalPart = appendOptionalPart;

И я попробовал несколько подходов, чтобы запустить функцию «Подготовить JSON»:

msg.payload = {
    "A_Key": "Value 1",
    "C_Key": msg.payload.C_Key,
    "Properties": {
        "B_Key": msg.payload.B_Key
    },
    optionalPart: msg.optionalPart
}

//for(var i =0; i<msg.mandatoryParts.length;i++)
//{  
//  msg.payload.Properties.push(msg.payload[msg.mandatoryKeys[i]].value);
//    msg.payload.Properties.push(msg.mandatoryKeys[i]);
//}
return msg;

Статическая часть вверху работает нормально, однако, как я могу динамически установить имя ключа элемента?Посмотрите на строку «AdditionalPart»: переменная «msg.optionalPart», но когда я пытаюсь получить к ней прямой доступ, Node Red жалуется на точку.Я попытался заключить его в экранированные кавычки, но Node Red также не нравится символ обратной косой черты в начале строки.Я также попробовал конкатенацию строк и, конечно, если я поместил имя переменной в кавычки, она выводилась дословно в выводе ...

Скомментированная часть внизу была моей первой попыткой зацикливания элементов, яЯ застрял здесь тоже.С благодарностью приветствуется любая помощь!

Вот изображение того, как выглядит поток:

Current configuration of the flow

1 Ответ

0 голосов
/ 30 января 2019

Это легко сделать с помощью JSONata, языка, облегчающего преобразование данных.

Основная часть вашего потока Node-RED будет узлом изменения с этим выражением JSONata:

payload.{"A_Key" :A_Key, "C_Key" :C_Key, "Properties" : {"B_Key" :B_Key, "F_Key" :F_Key, "X_Key" :X_Key}, "Extras" : {"D_Key" :D_Key, "E_Key" :E_Key }}

Это поток для импорта для вашего Node-RED, просто исправьте путь к имени файла:

[{"id":"52781b93.a86794","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"fc475896.7f6a68","type":"csv","z":"52781b93.a86794","name":"","sep":",","hdrin":true,"hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","x":430,"y":260,"wires":[["c6f562e7.6189c"]]},{"id":"282d5fcd.692cb","type":"debug","z":"52781b93.a86794","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":260,"wires":[]},{"id":"22fa22d.c2868de","type":"inject","z":"52781b93.a86794","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":260,"wires":[["93544cf8.57fad"]]},{"id":"93544cf8.57fad","type":"file in","z":"52781b93.a86794","name":"Read CSV","filename":"f1.csv","format":"utf8","chunk":false,"sendError":false,"x":280,"y":260,"wires":[["fc475896.7f6a68"]]},{"id":"c6f562e7.6189c","type":"change","z":"52781b93.a86794","name":"Prepare JSON","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.{\"A_Key\" :A_Key, \"C_Key\" :C_Key, \"Properties\" : {\"B_Key\" :B_Key, \"F_Key\" :F_Key, \"X_Key\" :X_Key}, \"Extras\" : {\"D_Key\" :D_Key, \"E_Key\" :E_Key }}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":260,"wires":[["282d5fcd.692cb"]]}]

EDIT: добавление потенциального ответа на ваш вопрос о ключе динамического элемента.

Если я правильно понял, вы хотите добавить к msg.payload ключ, который является переменным.Для этой цели вы можете использовать Имена вычисляемых свойств Javascript .

В вашем функциональном узле это будет выглядеть так:

msg.payload = {
    "A_Key": "Value 1",
    "C_Key": msg.payload.C_Key,
    "Properties": {
        "B_Key": msg.payload.B_Key
    },
    //optionalPart: msg.optionalPart
    [optionalPart]:["Z_Key"]
    // or [msg.optionalPart]:["Z_Key"] if more appropriate for your logic
}

У вас будет ключ свойства "Дополнения "добавлены к msg.payload.

В качестве дополнительного примечания (поскольку это не является частью вашего ОП), обратите внимание, что приведенный ниже код неясен и, вероятно, вызывает затруднения, если msg.payload.C_Key и msg.payload.B_Keyнеправильно инициализирован.

"C_Key": msg.payload.C_Key,
"B_Key": msg.payload.B_Key,
...