Преобразование сложного массива Json с помощью Jolt

avatar
PolygotP
1 июля 2021 в 18:34
223
2
0

При вызове внешнего API я получаю сложную структуру json, которую мне нужно преобразовать в простой json в соответствии с нашими потребностями. Я обнаружил, что jolt может преобразовывать json, но не может придумать спецификацию jolt.

Мой входной массив 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"
              }
            }
          }
        }
      ]
    }
  }
}

Моя выходная структура 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"
        }
      }
    }
  ]
}

Я попробовал несколько спецификаций толчков, но не смог добиться желаемого результата. Какой должна быть идеальная характеристика толчка для этого?

Источник

Ответы (2)

avatar
kasptom
1 июля 2021 в 18:52
2

Эта спецификация должна работать при использовании операции сдвига:

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

Редактировать #1:

Пояснение: Спецификация операции сдвига определяет, куда мы хотим поместить значения из входного json в результирующий json.

  1. Каждая пара ключ-значение в спецификации определяет отношение источник-цель. Например (начнем с самого простого): значение из ["item"]["name"] попадет под ключ ["name"] в выходном JSON.
 "items": {
    "*": {
      ...
    }
 }

часть говорит: "Для каждого элемента массива под ключом "items" выполните ..."

  1. Операция амперсанда "&X" позволяет нам сослаться на ключ, который находится на уровне X выше LHS (соответствующий ключ). Например: Представим, что у нас есть 57-й элемент массива элементов (считая с 0):
...
"name": "allocDetails[&2].team.name"
...

говорит: «Поместите значение, найденное под ключом "name" (то есть в item["items"][56]["team"]["name"], в 57-й элемент массива, помещенного под ключ "allocDetails".

'*' соответствует 57-му элементу. '&2' позволяет узнать, что элемент массива, над которым мы сейчас работаем, является 57-м элементом.

Have a look at the shift operation javadocs, especially at the "&" and "*" wildcards


Редактировать #2: учитывая комментарий otherDetails: Вы также можете подойти к этому так:

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

вышеупомянутое: помещает все ключи части products' (совпадающие с "*") в ключ с тем же именем ("&"), помещенный в "allocDetails[&3].team.product" выходной ключ json... с исключение ключа "otherDetails".

PolygotP
1 июля 2021 в 19:01
0

Спасибо за ответ. Не могли бы вы объяснить спецификацию?

PolygotP
1 июля 2021 в 19:18
0

Просто добавил еще один тег под продуктом, т. е. "otherDetails". Что мне делать, если я не хочу, чтобы этот тег под тегом продукта выводился.. "otherDetails": { "key": "Id", "value": "GEC" }

PolygotP
3 июля 2021 в 19:08
0

Спасибо за это .. Я также добавил комментарий ниже ..

avatar
PolygotP
1 июля 2021 в 19:38
1

Рабочий толчок --

  {
    "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"
                }
              }
            }
          }
        }
      }
    }
  }
]```
kasptom
1 июля 2021 в 22:29
0

Я добавил объяснение спецификации. Я также предложил другой подход для части otherDetails.

PolygotP
3 июля 2021 в 19:04
0

Да, я это видел.. Я подумал, что если у продукта есть больше данных, таких как «otherdetails», мы должны поместить все это как нуль в спецификацию json, как вы упомянули.. «product»: { «otherDetails»: null, «* ": "allocDetails[&3].team.product.&" } Вместо этого, если мы упомянем только обязательные поля, которые нам нужны, это будет коротким и перспективным, а также в случае, если новые данные будут добавлены в json (из третья сторона)