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.