Перейти к основному содержимому
Перейти к основному содержимому

other

title: Другие подходы к моделированию JSON slug: /integrations/data-formats/json/other-approaches description: Другие подходы к моделированию JSON keywords: ['json', 'formats']

Мы можем объявить ключ request как Nested. Подобно Tuple, мы должны указать подколонки.

flatten_nested

Параметр flatten_nested управляет поведением вложенных структур.

flatten_nested=1

Значение 1 (по умолчанию) не поддерживает произвольный уровень вложенности. С этим значением проще всего думать о вложенной структуре данных как о нескольких Array колонках одинаковой длины. Поля method, path и version в действительности являются отдельными Array(Type) колонками с одним критическим ограничением: длина полей method, path и version должна быть одинаковой. Если мы используем SHOW CREATE TABLE, это иллюстрируется следующим образом:

Ниже мы вставляем данные в эту таблицу:

Некоторые важные моменты, которые стоит отметить здесь:

  • Нам нужно использовать параметр input_format_import_nested_json, чтобы вставить JSON как вложенную структуру. Без этого мы обязаны развернуть JSON, т.е.

  • Вложенные поля method, path и version должны быть переданы как JSON массивы, т.е.

Колонки можно запрашивать с помощью точечной нотации:

Обратите внимание, что использование Array для подколонок означает, что весь спектр функций Array потенциально может быть использован, включая ARRAY JOIN — полезно, если ваши колонки имеют несколько значений.

flatten_nested=0

Это позволяет произвольный уровень вложенности и означает, что вложенные колонки остаются как единый массив Tuple — фактически они становятся тем же, что и Array(Tuple).

Это представляет собой предпочтительный способ и зачастую самый простой способ использовать JSON с Nested. Как мы покажем ниже, это требует, чтобы все объекты были списком.

Ниже мы воссоздаем нашу таблицу и повторно вставляем строку:

Некоторые важные моменты, которые стоит отметить здесь:

  • input_format_import_nested_json не требуется для вставки.

  • Тип Nested сохраняется в SHOW CREATE TABLE. Внутри эта колонка фактически является Array(Tuple(Nested(method LowCardinality(String), path String, version LowCardinality(String))))

  • В результате, мы обязаны вставлять request как массив, т.е.

Колонки можно снова запрашивать с помощью точечной нотации:

Пример

Более крупный пример вышеуказанных данных доступен в публичном бакете в s3 по адресу: s3://datasets-documentation/http/.

Учитывая ограничения и формат ввода для JSON, мы вставляем этот образец данных с помощью следующего запроса. Здесь мы устанавливаем flatten_nested=0.

Следующее выражение вставляет 10 миллионов строк, поэтому выполнение может занять несколько минут. Примените LIMIT, если это необходимо:

Запрашивать эти данные требует от нас доступа к полям запроса как массивам. Ниже мы резюмируем ошибки и HTTP-методы за фиксированный период времени.

Использование парных массивов

Парные массивы обеспечивают баланс между гибкостью представления JSON как строк и производительностью более структурированного подхода. Схема гибкая, так как любые новые поля могут быть потенциально добавлены в корень. Однако это требует значительно более сложного синтаксиса запросов и не совместимо со вложенными структурами.

В качестве примера рассмотрим следующую таблицу:

Чтобы вставить данные в эту таблицу, нам нужно структурировать JSON как список ключей и значений. Следующий запрос иллюстрирует использование JSONExtractKeysAndValues для достижения этой цели:

Обратите внимание, что колонка запроса остается вложенной структурой, представленной как строка. Мы можем вставить любые новые ключи в корень. Мы также можем иметь произвольные различия в самом JSON. Чтобы вставить в нашу локальную таблицу, выполните следующее:

Запрос этой структуры требует использования функции indexOf для определения индекса требуемого ключа (который должен быть согласован с порядком значений). Это может быть использовано для доступа к колонке значений, т.е. values[indexOf(keys, 'status')]. Нам все еще требуется метод разбора JSON для колонки запроса — в этом случае simpleJSONExtractString.