Функции для работы с JSON
В Яндекс.Метрике пользователями передаётся JSON в качестве параметров визитов. Для работы с таким JSON-ом, реализованы некоторые функции. (Хотя в большинстве случаев, JSON-ы дополнительно обрабатываются заранее, и полученные значения кладутся в отдельные столбцы в уже обработанном виде.) Все эти функции исходят из сильных допущений о том, каким может быть JSON, и при этом стараются почти ничего не делать.
Делаются следующие допущения:
- Имя поля (аргумент функции) должно быть константой;
- Считается, что имя поля в JSON-е закодировано некоторым каноническим образом. Например,
visitParamHas('{"abc":"def"}', 'abc') = 1
, ноvisitParamHas('{"\\u0061\\u0062\\u0063":"def"}', 'abc') = 0
- Поля ищутся на любом уровне вложенности, без разбора. Если есть несколько подходящих полей - берётся первое.
- В JSON-е нет пробельных символов вне строковых литералов.
visitParamHas(params, name)
Проверяет наличие поля с именем name
.
Синоним: simpleJSONHas
.
visitParamExtractUInt(params, name)
Пытается выделить число типа UInt64 из значения поля с именем name
. Если поле строковое, пытается выделить число из начала строки. Если такого поля нет, или если оно есть, но содержит не число, то возвращает 0.
Синоним: simpleJSONExtractUInt
.
visitParamExtractInt(params, name)
Аналогично для Int64.
Синоним: simpleJSONExtractInt
.
visitParamExtractFloat(params, name)
Аналогично для Float64.
Синоним: simpleJSONExtractFloat
.
visitParamExtractBool(params, name)
Пытается выделить значение true/false. Результат — UInt8.
Синоним: simpleJSONExtractBool
.
visitParamExtractRaw(params, name)
Возвращает значение поля, включая разделители.
Синоним: simpleJSONExtractRaw
.
Примеры:
visitParamExtractString(params, name)
Разбирает строку в двойных кавычках. У значения убирается экранирование. Если убрать экранированные символы не удалось, то возвращается пустая строка.
Синоним: simpleJSONExtractString
.
Примеры:
На данный момент не поддерживаются записанные в формате \uXXXX\uYYYY
кодовые точки не из basic multilingual plane (они переводятся не в UTF-8, а в CESU-8).
Следующие функции используют simdjson, который разработан под более сложные требования для разбора JSON. Упомянутое выше допущение 2 по-прежнему применимо.
isValidJSON(json)
Проверяет, является ли переданная строка валидным json значением.
Примеры:
JSONHas(json[, indices_or_keys]...)
Если значение существует в документе JSON, то возвращается 1
.
Если значение не существует, то возвращается 0
.
Примеры:
indices_or_keys
— это список из нуля или более аргументов каждый из них может быть либо строкой либо целым числом.
- Строка — это доступ к объекту по ключу.
- Положительное целое число — это доступ к n-му члену/ключу с начала.
- Отрицательное целое число — это доступ к n-му члену/ключу с конца.
Адресация элементов по индексу начинается с 1, следовательно элемент 0 не существует.
Вы можете использовать целые числа, чтобы адресовать как массивы JSON, так и JSON-объекты.
Примеры:
JSONLength(json[, indices_or_keys]...)
Возвращает длину массива JSON или объекта JSON.
Если значение не существует или имеет неверный тип, то возвращается 0
.
Примеры:
JSONType(json[, indices_or_keys]...)
Возвращает тип значения JSON.
Если значение не существует, то возвращается Null
.
Примеры:
JSONExtractUInt(json[, indices_or_keys]...)
JSONExtractInt(json[, indices_or_keys]...)
JSONExtractFloat(json[, indices_or_keys]...)
JSONExtractBool(json[, indices_or_keys]...)
Парсит JSON и извлекает значение. Эти функции аналогичны функциям visitParam
.
Если значение не существует или имеет неверный тип, то возвращается 0
.
Примеры:
JSONExtractString(json[, indices_or_keys]...)
Парсит JSON и извлекает строку. Эта функция аналогична функции visitParamExtractString
.
Если значение не существует или имеет неверный тип, то возвращается пустая строка.
У значения убирается экранирование. Если убрать экранированные символы не удалось, то возвращается пустая строка.
Примеры:
JSONExtract(json[, indices_or_keys...], Return_type)
Парсит JSON и извлекает значение с заданным типом данных.
Это обобщение предыдущих функций JSONExtract<type>
.
Это означает
JSONExtract(..., 'String')
выдает такой же результат, как JSONExtractString()
,
JSONExtract(..., 'Float64')
выдает такой же результат, как JSONExtractFloat()
.
Примеры:
JSONExtractKeysAndValues(json[, indices_or_keys...], Value_type)
Разбор пар ключ-значение из JSON, где значение имеет тип данных ClickHouse.
Пример:
JSONExtractKeys
Парсит строку JSON и извлекает ключи.
Синтаксис
Аргументы
json
— строка, содержащая валидный JSON.a, b, c...
— индексы или ключи, разделенные запятыми, которые указывают путь к внутреннему полю во вложенном объекте JSON. Каждый аргумент может быть либо строкой для получения поля по ключу, либо целым числом для получения N-го поля (индексирование начинается с 1, отрицательные числа используются для отсчета с конца). Если параметр не задан, весь JSON разбирается как объект верхнего уровня. Необязательный параметр.
Возвращаемые значения
Массив с ключами JSON.
Пример
Запрос:
Результат:
JSONExtractRaw(json[, indices_or_keys]...)
Возвращает часть JSON в виде строки, содержащей неразобранную подстроку.
Если значение не существует, то возвращается пустая строка.
Пример:
JSONExtractArrayRaw(json[, indices_or_keys]...)
Возвращает массив из элементов JSON массива, каждый из которых представлен в виде строки с неразобранными подстроками из JSON.
Если значение не существует или не является массивом, то возвращается пустой массив.
Пример:
JSONExtractKeysAndValuesRaw
Извлекает необработанные данные из объекта JSON.
Синтаксис
Аргументы
json
— строка, содержащая валидный JSON.p, a, t, h
— индексы или ключи, разделенные запятыми, которые указывают путь к внутреннему полю во вложенном объекте JSON. Каждый аргумент может быть либо строкой для получения поля по ключу, либо целым числом для получения N-го поля (индексирование начинается с 1, отрицательные числа используются для отсчета с конца). Если параметр не задан, весь JSON парсится как объект верхнего уровня. Необязательный параметр.
Возвращаемые значения
-
Массив с кортежами
('key', 'value')
. Члены кортежа — строки. -
Пустой массив, если заданный объект не существует или входные данные не валидный JSON.
Тип: Array(Tuple(String, String).
Примеры
Запрос:
Результат:
Запрос:
Результат:
Запрос:
Результат:
JSON_EXISTS(json, path)
Если значение существует в документе JSON, то возвращается 1.
Если значение не существует, то возвращается 0.
Пример:
До версии 21.11 порядок аргументов функции был обратный, т.е. JSON_EXISTS(path, json)
JSON_QUERY(json, path)
Парсит JSON и извлекает значение как JSON массив или JSON объект.
Если значение не существует, то возвращается пустая строка.
Пример:
Результат:
До версии 21.11 порядок аргументов функции был обратный, т.е. JSON_QUERY(path, json)
JSON_VALUE(json, path)
Парсит JSON и извлекает значение как JSON скаляр.
Если значение не существует, то возвращается пустая строка.
Пример:
Результат:
До версии 21.11 порядок аргументов функции был обратный, т.е. JSON_VALUE(path, json)
toJSONString
Сериализует значение в JSON представление. Поддерживаются различные типы данных и вложенные структуры.
По умолчанию 64-битные целые числа и более (например, UInt64
или Int128
) заключаются в кавычки. Настройка output_format_json_quote_64bit_integers управляет этим поведением.
Специальные значения NaN
и inf
заменяются на null
. Чтобы они отображались, включите настройку output_format_json_quote_denormals.
Когда сериализуется значение Enum, то функция выводит его имя.
Синтаксис
Аргументы
value
— значение, которое необходимо сериализовать. Может быть любого типа.
Возвращаемое значение
- JSON представление значения.
Тип: String.
Пример
Первый пример показывает сериализацию Map. Во втором примере есть специальные значения, обернутые в Tuple.
Запрос:
Результат:
Смотрите также