首页 文章

Jolt:从属性合并数组

提问于
浏览
0

我正在尝试从包含在某些(但不是全部)输入元素中的数组中提取和合并对象 . 使用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文档及其单元测试 . 一点帮助?

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" ]
        }
      ]
    }
    

相关问题