简体   繁体   中英

JOLT shift transformation: filter by inner value of a property (not the name)

I am trying to transform a JSON using Jolt transformation looking for some input here. I am trying to filter by the inner value of the attribute.

My goal is to get an array that contains only the items with the typeName 'xx'.

Here is my input and expected output:

Input :

{
  "id": 11,
  "item": [
    {
      "id": "11_1",
      "action": "add",
      "type": {
        "id": "11_1_xx",
        "typeName": "xx"
      },
      "item": [
        {
          "id": "11_1_1",
          "action": "add",
          "type": {
            "id": "11_1_1_zz",
            "typeName": "zz"
          },
          "item": [
            {
              "id": "11_1_1_1",
              "action": "add",
              "type": {
                "id": "11_1_1_1_xx",
                "typeName": "xx"
              }
            }
          ]
        },
        {
          "id": "11_1_2",
          "action": "add",
          "type": {
            "id": "11_1_2_xx",
            "typeName": "xx"
          },
          "item": [
            {
              "id": "11_1_2_1",
              "action": "add",
              "type": {
                "id": "11_1_2_1_zz",
                "typeName": "zz"
              }
            }
          ]
        }
      ]
    }
  ]
}

Expected output :

[
  {
    "id": "11_1",
    "action": "add",
    "type": {
      "id": "11_1_xx",
      "typeName": "xx"
    }
  },
  {
    "id": "11_1_1_1",
    "action": "add",
    "type": {
      "id": "11_1_1_1_xx",
      "typeName": "xx"
    }
}, {
    "id": "11_1_2",
    "action": "add",
    "type": {
      "id": "11_1_2_xx",
      "typeName": "xx"
    }
  }
]


Can you please help me to write a simple spec that will do this?

Need to separate the objects by both the id and type.typeName values in the first transformation spec, in order to filter out by type.typeName=xx within the next spec long with distinctly picked id values through use of @(1,id).@(1,typeName) identifiers on the Right Hand Side for the leaf elements such as

[
  {
    "operation": "shift",
    "spec": {
      "item": {
        "*": {
          "item": {
            "*": {
              "item": {
                "*": {
                  "type": {
                    "@(1,id)": "@(1,id).@(1,typeName).id",
                    "@(1,action)": "@(1,id).@(1,typeName).action",
                    "*": "@(1,id).@(1,typeName).&1.&" // &1 replicates key name "type"
                  }
                }
              },
              "type": {
                "@(1,id)": "@(1,id).@(1,typeName).id",
                "@(1,action)": "@(1,id).@(1,typeName).action",
                "*": "@(1,id).@(1,typeName).&1.&" // & replicates the values of the elements nested within the "type" object
              }
            }
          },
          "type": {
            "@(1,id)": "@(1,id).@(1,typeName).id",
            "@(1,action)": "@(1,id).@(1,typeName).action",
            "*": "@(1,id).@(1,typeName).&1.&"
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "xx": ""
      }
    }
  }
]

the demo on the site http://jolt-demo.appspot.com/ is

在此处输入图像描述

You may consider another library Josson that a simple statement can do the job. And the function even supports unknown and unlimited number of path levels.

https://github.com/octomix/josson

Deserialization

Josson josson = Josson.fromJsonString(
    "{" +
    "  \"id\": 11," +
    "  \"item\": [" +
    "    {" +
    "      \"id\": \"11_1\"," +
    "      \"action\": \"add\"," +
    "      \"type\": {" +
    "        \"id\": \"11_1_xx\"," +
    "        \"typeName\": \"xx\"" +
    "      }," +
    "      \"item\": [" +
    "        {" +
    "          \"id\": \"11_1_1\"," +
    "          \"action\": \"add\"," +
    "          \"type\": {" +
    "            \"id\": \"11_1_1_zz\"," +
    "            \"typeName\": \"zz\"" +
    "          }," +
    "          \"item\": [" +
    "            {" +
    "              \"id\": \"11_1_1_1\"," +
    "              \"action\": \"add\"," +
    "              \"type\": {" +
    "                \"id\": \"11_1_1_1_xx\"," +
    "                \"typeName\": \"xx\"" +
    "              }" +
    "            }" +
    "          ]" +
    "        }," +
    "        {" +
    "          \"id\": \"11_1_2\"," +
    "          \"action\": \"add\"," +
    "          \"type\": {" +
    "            \"id\": \"11_1_2_xx\"," +
    "            \"typeName\": \"xx\"" +
    "          }," +
    "          \"item\": [" +
    "            {" +
    "              \"id\": \"11_1_2_1\"," +
    "              \"action\": \"add\"," +
    "              \"type\": {" +
    "                \"id\": \"11_1_2_1_zz\"," +
    "                \"typeName\": \"zz\"" +
    "              }" +
    "            }" +
    "          ]" +
    "        }" +
    "      ]" +
    "    }" +
    "  ]" +
    "}");
    

Transformation

JsonNode node = josson.getNode(
    "cumulateCollect(item[type.typeName='xx']*.field(item:), item).flatten(1)");
System.out.println(node.toPrettyString());

Output

[ {
  "id" : "11_1",
  "action" : "add",
  "type" : {
    "id" : "11_1_xx",
    "typeName" : "xx"
  }
}, {
  "id" : "11_1_2",
  "action" : "add",
  "type" : {
    "id" : "11_1_2_xx",
    "typeName" : "xx"
  }
}, {
  "id" : "11_1_1_1",
  "action" : "add",
  "type" : {
    "id" : "11_1_1_1_xx",
    "typeName" : "xx"
  }
} ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM