Как проанализировать JSON с несовместимым типом данных? - PullRequest
0 голосов
/ 14 ноября 2018

Мне нужно создать отчет csv из файла JSON следующей структуры (упрощено настолько, насколько я посчитал нужным):

{
  "data": [
    {
      "id": "123",
      "foo": {
        "item": {
          "value": "foo_good",
          "bar_id": "1"
        }
      },
      "bar": {
        "item": {
          "id": "1",
          "value": "bar_value_1a"
        }
      },
      "var": {
        "item": {
          "value": "var_value_1a",
          "bar_id": "1"
        }
      }
    },
    {
      "id": "456",
      "foo": {
        "item": [
          {
            "value": "foo_bad",
            "bar_id": "1"
          },
          {
            "value": "foo_good",
            "bar_id": "2"
          },
          {
            "value": "foo_good",
            "bar_id": "2"
          },
          {
            "value": "foo_bad",
            "bar_id": "3"
          },
          {
            "value": "foo_good",
            "bar_id": "4"
          }
        ]
      },
      "bar": {
        "item": [
          {
            "id": "1",
            "value": "bar_value_2a"
          },
          {
            "id": "2",
            "value": "bar_value_2b"
          },
          {
            "id": "3",
            "value": "bar_value_2c"
          },
          {
            "id": "4",
            "value": "bar_value_2d"
          }
        ]
      },
      "var": {
        "item": [
          {
            "value": "var_value_2a",
            "bar_id": "1"
          },
          {
            "value": "var_value_2b",
            "bar_id": "2"
          },
          {
            "value": "var_value_2c",
            "bar_id": "3"
          },
          {
            "value": "var_value_2d",
            "bar_id": "4"
          }
        ]
      }
    }
  ]
}

Структура данных:

  1. foo.item и var.item подключены к bar.item с bar_id
  2. Один или несколько foo.item указывают на один bar.item
  3. Несколько foo.item, указывающие на одно и то же bar.item, будут иметь одинаковые foo.item.value
  4. Ровно один var.item указывает на один bar.item
  5. Все товары отсортированы по bar_id
  6. Формат несовместим . bar.item - это объект, если есть только один элемент, в противном случае это массив (также относится к foo.item и var.item)
  7. Я застрял в этом формате

Выходной отчет:

  1. Обработка всех data объектов
  2. Создать отчет для каждого bar.item, который не имеет соответствующий foo.item со значением foo_bad
  3. Выходной формат: .id, .bar.item.value, .var.item.value

Моя попытка:

Временный сценарий jq, который я сейчас использую, отбрасывает несколько bar.item и т. Д. И создает простую оценку реальных данных:

.data[]
| .foo.item |= if type=="array" then .[0] else . end
| .bar.item |= if type=="array" then .[0] else . end
| .var.item |= if type=="array" then .[0] else . end
| select(.foo.item.value != "foo_bad")
| [.id,.bar.item.value,.var.item.value]
| @csv

Что выводит следующее:

"123","bar_value_1a","var_value_1a"

Желаемый выход:

"123","bar_value_1a","var_value_1a"
"456","bar_value_2b","var_value_2b"
"456","bar_value_2d","var_value_2d"

Я предпочитаю использовать jq, хотя я не настаиваю на этом.

1 Ответ

0 голосов
/ 14 ноября 2018

Я бы посоветовал вам начать с того, чтобы .foo.item, .bar.item и .var.item всегда были массивами. Это можно сделать с помощью следующей вспомогательной функции:

def w: if type=="array" then . else [.] end;

Ваш jq фильтр будет начинаться следующим образом:

.data[]
| .foo.item |= w
| .bar.item |= w
| .var.item |= w

Что вы будете делать дальше, зависит от того, что вы хотите сделать со всеми этими массивами, но я убедился, что следующий результат дает результат, который вы указали, как вы хотите:

.data[]
| .foo.item |= w
| .bar.item |= w
| .var.item |= w
| range(0; .foo.item | length) as $i
| select(.foo.item[$i].value != "foo_bad")
| select(.bar.item[$i].value)
| [.id,.bar.item[$i].value,.var.item[$i].value]
| @csv
...