简体   繁体   English

使用 Jolt 转换复杂的 Json 数组

[英]Transform complex Json array using Jolt

When Calling an external API I am receiving a complex json structure, the same I need to transform into a simple json as per our need.当调用外部 API 时,我收到一个复杂的 json 结构,同样我需要根据我们的需要将其转换为一个简单的 json。 I found jolt has the capability to transform a json but not able to come up with the jolt spec.我发现 jolt 具有转换 json 的能力,但无法提出 jolt 规范。

My input Json array --我的输入 Json 数组——

{
  "attribute": [
    "teamalloc",
    "prodAlloc"
  ],
  "item": {
    "id": "abcde",
    "name": "Champak Kumar",
    "allocDetails": {
      "updatedAt": "2020-08-10T14:26:48-07:00",
      "token": 1134,
      "items": [
        {
          "allocation": 0.2,
          "team": {
            "id": 90,
            "name": "Some Team Name 1",
            "createdAt": "2010-01-19T10:52:52-07:00"
          }
        },
        {
          "allocation": 0.9,
          "team": {
            "id": 80,
            "name": "Some Team Name 2",
            "createdAt": "2010-01-19T10:52:52-07:00",
            "product": {
              "id": 20,
              "name": "Some Product Name 1",
              "otherDetails": {
                "key": "Id",
                "value": "GEC"
              }
            }
          }
        },
        {
          "allocation": 0.1,
          "team": {
            "id": 10,
            "name": "Some Team Name 3",
            "createdAt": "2010-01-19T10:52:52-07:00",
            "product": {
              "id": 22,
              "name": "Some Product Name 2",
              "otherDetails": {
                "key": "Id1",
                "value": "GEC1"
              }
            }
          }
        }
      ]
    }
  }
}

My output Json structure should look like --我的输出 Json 结构应该是这样的——

{
  "name": "Champak Kumar",
  "allocDetails": [
    {
      "allocation": 0.2,
      "team": {
        "id": 90,
        "name": "Some Team Name 1"
      }
    },
    {
      "allocation": 0.9,
      "team": {
        "id": 80,
        "name": "Some Team Name 2",
        "product": {
          "id": 20,
          "name": "Some Product Name 1"
        }
      }
    },
    {
      "allocation": 0.1,
      "team": {
        "id": 10,
        "name": "Some Team Name 3",
        "product": {
          "id": 22,
          "name": "Some Product Name 2"
        }
      }
    }
  ]
}

I tried multiple jolt spec but couldn't come up with the desired output.我尝试了多个 jolt 规范,但无法提出所需的输出。 What should be the ideal jolt spec for this?理想的震动规格应该是什么?

This spec should using shift operation should work:这个规范应该使用移位操作应该工作:

[
  {
    "operation": "shift",
    "spec": {
      "item": {
        "name": "name",
        "allocDetails": {
          "items": {
            "*": {
              "allocation": "allocDetails[&1].allocation",
              "team": {
                "id": "allocDetails[&2].team.id",
                "name": "allocDetails[&2].team.name",
                "product": "allocDetails[&2].team.product"
              }
            }
          }
        }
      }
    }
  }
]

Edit #1:编辑#1:

The explanation: The shift operation spec defines where do we want to put the values from the input json in the result json.解释:移位操作规范定义了我们要将输入 json 中的值放在结果 json 中的什么位置。

  1. Each key - value pair in the spec defines the source - target relation.规范中的每个键-值对定义了源-目标关系。 For example (let's start from the simplest one): value from the ["item"]["name"] will land under the ["name"] key in the output JSON.例如(让我们从最简单的开始):来自["item"]["name"]将落在输出 JSON 中的["name"]键下。
  2. The
 "items": {
    "*": {
      ...
    }
 }

part says: "For each element of the array under the 'items' key do ... "部分说:“对于 'items' 键下的数组的每个元素,请执行...

  1. The ampersand operator "&X" lets us reference the key that is X levels above the LHS (the key in question).与号运算符"&X"让我们引用 LHS 上方X级的键(有问题的键)。 For example: Let's imagine we have the 57th element of the items array (counting from 0):例如:假设我们有 items 数组的第 57 个元素(从 0 开始计数):
...
"name": "allocDetails[&2].team.name"
...

says: "Place the value found under the "name" key (that is in item["items"][56]["team"]["name"] in the 57th element of the array placed under the "allocDetails" key.说:“将找到的值放在"name"键下(即在item["items"][56]["team"]["name"]中的数组的第 57 个元素中放置在"allocDetails"键下.

'*' matches the 57th element. '*' 匹配第 57 个元素。 '&2' lets us find out that the element of the array we are working on right now is the 57th element. '&2' 让我们发现我们现在正在处理的数组的元素是第 57 个元素。

Have a look at the shift operation javadocs , especially at the "&" and "*" wildcards查看shift operation javadocs ,尤其是"&""*"通配符


Edit #2: considering the otherDetails comment: You could also approach it like this:编辑 #2:考虑otherDetails评论:您也可以这样处理它:

...
    "team": {
        "id": "allocDetails[&2].team.id",
        "name": "allocDetails[&2].team.name",
        "product": {
            "otherDetails": null,
            "*": "allocDetails[&3].team.product.&"
        }
    }
...

the above: puts all of the products ' part keys (matched by the "*" ) to the key with the same name ( "&" ) placed in the "allocDetails[&3].team.product" output json's key... with the exception of the "otherDetails" key.以上:将所有products的部分键(由"*"匹配)放到具有相同名称( "&" )的键中,放在"allocDetails[&3].team.product"输出 json 的键中...除了"otherDetails"键。

Working jolt spec --工作颠簸规格——

  {
    "operation": "shift",
    "spec": {
      "item": {
        "name": "name",
        "allocDetails": {
          "items": {
            "*": {
              "allocation": "allocDetails[&1].allocation",
              "team": {
                "id": "allocDetails[&2].team.id",
                "name": "allocDetails[&2].team.name",
                "product": {
                  "id": "allocDetails[&3].team.product.id",
                  "name": "allocDetails[&3].team.product.name"
                }
              }
            }
          }
        }
      }
    }
  }
]```

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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