Jolt:从属性合并数组

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

我正在尝试从包含在某些(但不是全部)输入元素中的数组中提取和合并对象。使用JOLT JSON转换库。

此外,我正在尝试合并的数组包含并不总是具有相同属性的对象。一些密钥可能存在于某些密钥中,但其他密钥则不存在

示例是人为/无意义的简化,但具有我们数据的一般形式。

输入:

{
  "Widgets": [
    {
      "Id": "1",
      "PetFriendly": "True",
      "Features": [
        {
          "Name": "Easy Button",
          "Type": "Button"
        },
        {
          "Name": "Lunch Lever",
          "Type": "Food Service",
          "MenuItems": [
            "Pizza",
            "Cheezburger"
          ]
        }
      ]
    },
    {
      "Id": "2",
      "PetFriendly": "True"
    },
    {
      "Id": "3",
      "PetFriendly": "False",
      "Features": [
        {
          "Name": "Missles",
          "Type": "Attack"
        }
      ]
    },
    {
      "Id": "4",
      "PetFriendly": "False",
      "Features": [
        {
          "Name": "Bombs",
          "Type": "Attack",
          "MenuItems": [
            "Rat Poison"
          ]
        }
      ]
    }
  ]
}

期望的输出:

  {
    "Widgets": [
      {
        "Id": "1"
        "PetFriendly": "True"
      },
      {
        "Id": "2"
        "PetFriendly": "True"
      },
      {
        "Id": "3",
        "PetFriendly": "False"
      },
      {
        "Id": "4",
        "PetFriendly": "False"
      }
    ],
    "Features": [
      {
        "WidgetId": "1",
        "Name": "Easy Button",
        "Type": "Button"
      },
      {
        "WidgetId": "1",
        "Name": "Lunch Lever",
        "Type": "Food Service",
        "MenuItems": [
            "Pizza",
             "Cheezburger"
         ]
      },
      {
        "WidgetId": "3",
        "Name": "Missles",
        "Type": "Attack"
      },
      {
        "WidgetId": "4",
        "Name": "Bombs",
        "Type": "Attack",
        "MenuItems": [
          "Rat Poison"
        ]
      }
    ]
  }

我尝试了很多变换但没有成功,并阅读了所有的ShiftR文档及其单元测试。一点帮助?

json transform jolt
2个回答
0
投票

规格

[
  {
    "operation": "shift",
    "spec": {
      "Widgets": {
        "*": {
          // build the finished "Widgets" output
          "Id": "Widgets[&1].Id",
          "PetFriendly": "Widgets[&1].PetFriendly",
          // 
          // Process the Features, by pushing the Id
          //  down into them, but maintain the same doubly
          //  nested structure.
          // Shift works property by property, so first 
          //  fix the properties in side each Features element,
          //  (pulling ID down).
          // Then in a 2nd Shift can accumulate things into array. 
          "Features": {
            "*": {
              "@(2,Id)": "temp[&3].Features[&1].WidgetId",
              "*": "temp[&3].Features[&1].&"
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      // passthru
      "Widgets": "Widgets",
      "temp": {
        "*": {
          "Features": {
            // walk thru the doubly nested structure an
            //  now accumulate all non-null itens into 
            //  the the final Features array.
            "*": "Features[]"
          }
        }
      }
    }
  }
]

0
投票

最后让它使用下面的规范,但它有一个不良的副作用:它留下空的默认数组。有没有办法删除空数组,或者在默认步骤中标记它们,以便删除它们?我检查了this GitHub issue但不确定如何将其转换为字符串数组。谁有更好的解决方案?

[
  // First fill in default value for "MenuItems" since not all Features have it.
  {
    "operation": "default",
    "spec": {
      "Widgets[]": {
        "*": {
          "Features[]": {
            "*": {
              "MenuItems": []
            }
          }
        }
      }
    }
  },
  {
    // Extract the Features' properties into arrays. The defaults added above ensure that we can merge the arrays into Feature objects as in this example: 
    // https://github.com/bazaarvoice/jolt/blob/master/jolt-core/src/test/resources/json/shiftr/mergeParallelArrays2_and-do-not-transpose.json.
    "operation": "shift",
    "spec": {
      "Widgets": {
        "*": {
          "Id": "Widgets[&1].Id",
          "PetFriendly": "Widgets[&1].PetFriendly",
          "Features": {
            "*": {
              "@(2,Id)": "temp.WidgetId",
              "Name": "temp.Name",
              "Type": "temp.Type",
              "MenuItems": "temp.MenuItems[]"
            }
          }
        }
      }
    }
  },
  // Finally merge the arrays into Feature objects.
  {
    "operation": "shift",
    "spec": {
      "Widgets": "Widgets",
      "temp": {
        "WidgetId": {
          "*": "Features[&0].WidgetId"
        },
        "Name": {
          "*": "Features[&0].Name"
        },
        "Type": {
          "*": "Features[&0].Type"
        },
        "MenuItems": {
          "*": "Features[&0].MenuItems"
        }
      }
    }
  }
]

结果:

{
  "Widgets": [
    {
      "Id": "1",
      "PetFriendly": "True"
    },
    {
      "Id": "2",
      "PetFriendly": "True"
    },
    {
      "Id": "3",
      "PetFriendly": "False"
    },
    {
      "Id": "4",
      "PetFriendly": "False"
    }
  ],
  "Features": [
    {
      "WidgetId": "1",
      "Name": "Easy Button",
      "Type": "Button",
      "MenuItems": []
    },
    {
      "WidgetId": "1",
      "Name": "Lunch Lever",
      "Type": "Food Service",
      "MenuItems": [ "Pizza", "Cheezburger" ]
    },
    {
      "WidgetId": "3",
      "Name": "Missles",
      "Type": "Attack",
      "MenuItems": []
    },
    {
      "WidgetId": "4",
      "Name": "Bombs",
      "Type": "Attack",
      "MenuItems": [ "Rat Poison" ]
    }
  ]
}
© www.soinside.com 2019 - 2024. All rights reserved.