JOLT 转换构建对象数组,将同一对象中的属性分组

JOLT transformation build array of objects grouping attributes in the same object

我正在尝试使用不同的输入值组合构造一个名为目录的对象数组,但无法在同一个对象中设置某些属性。这是目前的进度:

[
  {
    "operation": "shift",
    "spec": {
      "new": {
        "bc_sku_channel": {
          "*": {
            "Partner": null, //ignore if value is Partner 
            "*": {
              "#BC": "catalogs[#3].catalog",
              "@1": "catalogs[#3].channel"
            }
          }
        },
        "bc_sku_partner": {
          "*": {
            "#BC": "catalogs[].catalog", // don't know which index should be here to group these 3 attributes into the same object
            "#Partner": "catalogs[].channel", // tried #3,#2,#1,#4 but doesn't work
            "@": "catalogs[].partner"
          }
        },
        "cc_sku_channel": {
          "*": {
            "Partner": null, //ignore if value is Partner 
            "*": {
              "#CC": "catalogs[#3].catalog",
              "@1": "catalogs[#3].channel"
            }
          }
        }
      }
    }
  }
]

输入:

{
  "new": {
    "bc_sku_partner": [
      "Amazon",
      "Ebay"
    ],
    "bc_sku_channel": [
      "Partner",
      "Online",
      "Store"
    ],
    "cc_sku_channel": [
      "Store"
    ]
  }
}

预期输出:

 {
  "catalogs": [
    {
      "catalog": "BC",
      "channel": "Partner",
      "partner": "Amazon"
    },
    {
      "catalog": "BC",
      "channel": "Partner",
      "partner": "Ebay"
    },
    {
      "catalog": "BC",
      "channel": "Online"
    },
    {
      "catalog": "BC",
      "channel": "Store"
    },
    {
      "catalog": "CC",
      "channel": "Store"
    }
  ]
}

现在我只能构建最后 3 个对象。

备注:

如果频道是在线商店,则对象不应具有合作伙伴属性。

对于每个合作伙伴,渠道属性应始终为 合作伙伴

此规范产生预期的输出

假定 bc_cc_ 前缀是动态的版本:

可以在这个答案的末尾找到更简单的版本。

[
  {
    "operation": "shift",
    "spec": {
      "new": {
        "*_sku_partner": {      // 1
          "*": {                // 2
            "*": {              // 3
              "@1": {           // 4
                "": "partner__&1__&(4,1).partner",              // 5
                "#Partner": "partner__&1__&(4,1).channel",        // 6
                "$(3,1)": "partner__&1__&(4,1).catalogLowerCase"  // 7
              }
            }
          }
        },
        "*_sku_channel": {
          "*": {
            "Partner": null,        // 8
            "*": {
              "@1": {
                "": "channel__&1__&(4,1).channel",
                "$(3,1)": "channel__&1__&(4,1).catalogLowerCase"
              }
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",            // 9
    "spec": {
      "partner__*": "catalogs[#1]",
      "channel__*": "catalogs[#1]"
    }
  },
  {
    "operation": "modify-default-beta",  // 10
    "spec": {
      "catalogs": {
        "*": {
          "catalog": "=toUpper(@(1,catalogLowerCase))"
        }
      }
    }
  },
  {
    "operation": "shift",  // 11
    "spec": {
      "catalogs": {
        "*": {
          "catalogLowerCase": null,
          "*": "&2[&1].&"
        }
      }
    }
  }
]

第一个操作是最棘手的,我猜: 它创建一个具有唯一条目的字典,例如:

{
  "channel__Online__bc" : {
    "catalogLowerCase" : "bc",
    "channel" : "Online"
  }
  // ...
  "partner__Amazon__bc": {
    "catalogLowerCase": "bc",
    "channer": "Partner",
    "partner": "Amazon"
  }
}

来自:

// ...
"bc_sku_partner": [
  "Amazon",
  "Ebay"
]
// ...

让我们关注为“Amazon”生成的第一个条目:

广告。 1. *_sku_partner 匹配 "bc_sku_partner"。您还可以将星号替换为明确的 bc 值,而不是广告中的 $(3,1)。 7 位 #BC

广告。 2.匹配["Amazon", ...]列表的元素。

广告。 3. 我们现在在“亚马逊”里面了:D

广告。 4. 我们进入“亚马逊”并找到它 (@1)。相关文档:@ shift wildcard

广告。 5. 查看 ($ wildcard docs)

'$' has the same syntax as the '&' wildcard, and can be read as, dereference to get a value, and then use that value as the data to be output.

</code> 上升一级,获取值 (<code>"Amazon") 并将其放在 "partner__&1__&(4,1).partner: 键下。 "partner__&1__&(4,1)""Amazon" 元素生成:"partner__Amazon__bc"&(4,1) 在这里的意思是:

Go up 4 levels (we are at "bc_sku_partner") and take the value matched by the asterisk. See: & wildcard docs

广告。 6. 将 "Partner" 字符串放在 "channel" 键下(在 "partner": "Amazon" key-value 旁边)。

广告。 7. 再次 $(3,1) 但在这里我们找到与星号匹配的 "bc" 并将其放在 "catalogLowerCase" 键下。

"*_sku_channel"部分比较相似,就不多说了。 在广告。 8. 是删除 "Partner" 条目。

广告。 9、二班作业。它的目的是将第一个移位操作生成的字典转换为放置在 "catalogs" 键下的列表。 # wildcard 文档在这里可能会有用。

广告。 10 和 11 将 "catalogLowerCase": "bc" 替换为 "catalog": "BC"。与 "Ebay""Online""Store" 条目相关的类似 "catalogLowerCase" 字段也是如此。

尝试逐步应用操作,以查看中间结果。我推荐这个网站进行测试:https://jolt-demo.appspot.com/。它也有很多例子。


编辑:

其他方法,如果 bc_cc_ 前缀不是动态的。

[
  {
    "operation": "shift",
    "spec": {
      "new": {
        "bc_sku_partner": { // 1
          "*": { // 2
            "*": { // 3
              "@1": { // 4
                "": "partner__&1__bc.partner", // 5
                "#Partner": "partner__&1__bc.channel", // 6
                "#BC": "partner__&1__bc.catalog" // 7
              }
            }
          }
        },
        "bc_sku_channel": {
          "*": {
            "Partner": null,
            "*": {
              "@1": {
                "": "channel__&1__bc.channel",
                "#BC": "channel__&1__bc.catalog"
              }
            }
          }
        },
        "cc_sku_channel": {
          "*": {
            "Partner": null,
            "*": {
              "@1": {
                "": "channel__&1__cc.channel",
                "#CC": "channel__&1__cc.catalog"
              }
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "partner__*": "catalogs[#1]",
      "channel__*": "catalogs[#1]"
    }
  }
]