Ищете руководство?
Ознакомьтесь с нашим руководством по лучшим практикам работы с JSON: в нём вы найдёте примеры, расширенные возможности и рекомендации по использованию типа JSON.
JSON хранит документы JavaScript Object Notation (JSON) в одном столбце.
В ClickHouse Open-Source тип данных JSON считается готовым к использованию в продакшн, начиная с версии 25.3. В предыдущих версиях использовать этот тип в продакшн не рекомендуется.
JSON, можно использовать следующий синтаксис:
Когда использовать тип JSON
JSON предназначен для запросов, фильтрации и агрегации по отдельным полям в объектах JSON с динамической или непредсказуемой структурой. Для этого объекты JSON разбиваются на отдельные подстолбцы, что значительно уменьшает объём читаемых данных и ускоряет запросы по выбранным полям по сравнению с такими альтернативами, как Map или разбор строк.
Однако у этого подхода есть важные недостатки:
- Более медленные
INSERT- Разбиение JSON на подстолбцы, определение типов и управление гибкими структурами хранения делают вставку медленнее по сравнению с хранением JSON в виде простого столбцаString. - Медленнее при чтении объектов целиком - Если вам нужно получать JSON-документы целиком, а не отдельные поля, тип
JSONработает медленнее, чем чтение из столбцаString. Дополнительные затраты на восстановление объектов из отдельных подстолбцов не дают преимуществ, если вы не выполняете запрос по отдельным полям. - Дополнительные накладные расходы на хранение - Поддержка отдельных подстолбцов создаёт дополнительные структурные накладные расходы по сравнению с хранением JSON как одного строкового значения.
Используйте тип JSON, когда:
- У ваших данных динамическая или непредсказуемая структура, а ключи различаются от документа к документу
- Типы полей или схемы меняются со временем либо различаются между записями
- Вам нужно выполнять запросы, фильтровать или агрегировать данные по определённым путям внутри объектов JSON, структуру которых невозможно заранее предсказать
- Ваш сценарий предполагает работу с полуструктурированными данными, такими как журнал, события или пользовательский контент с непоследовательными схемами
Используйте столбец String (или структурированные типы), когда:
- Структура ваших данных известна и стабильна — в этом случае лучше использовать обычные столбцы, типы
Tuple,Array,DynamicилиVariant - Документы
JSONрассматриваются как непрозрачные blob-объекты, которые только хранятся и извлекаются целиком, без анализа на уровне полей - Вам не нужно выполнять запросы или фильтровать данные по отдельным полям JSON в базе данных
JSON— это просто формат передачи/хранения, а не формат, который анализируется в ClickHouse
Создание JSON
В этом разделе мы рассмотрим различные способы создания JSON.
Использование JSON в определении столбца таблицы
Query (Example 1)
Response (Example 1)
Query (Example 2)
Response (Example 2)
Использование CAST с ::JSON
Различные типы можно преобразовывать с помощью специального синтаксиса ::JSON.
CAST из String в JSON
Query
Response
CAST из Tuple в JSON
Query
Response
CAST из Map в JSON
Query
Response
JSON-пути хранятся в развёрнутом виде. Это означает, что, когда объект JSON формируется из пути вида вернёт:а не:
a.b.c,
невозможно определить, следует ли строить объект как { "a.b.c" : ... } или как { "a": { "b": { "c": ... } } }.
В нашей реализации всегда предполагается второй вариант.Например:Запрос
Ответ
Чтение JSON-путей как подстолбцов
ТипJSON поддерживает чтение каждого JSON-пути как отдельного подстолбца.
Если тип запрошенного пути не указан в объявлении типа JSON,
то подстолбец этого пути всегда будет иметь тип Dynamic.
Например:
Query
Response
Query (Reading JSON paths as sub-columns)
Response (Reading JSON paths as sub-columns)
getSubcolumn, чтобы получать подстолбцы из типа JSON:
Query
Response
json['key']. Вложенный доступ поддерживается через цепочку обращений:
Query
Response
Nullable(JSON), возвращая то же значение и тот же тип, что и
эквивалентный точечный синтаксис, и следуя тем же правилам nullability, что и json.key: путь, который может представлять
NULL (Dynamic либо типизированный путь, который можно обернуть в Nullable), для строки со значением NULL даёт NULL,
тогда как типизированный путь, не допускающий NULL, например Array или Map, сохраняет там своё значение по умолчанию.
Цепочка обращений через квадратные скобки сворачивается в один JSON-путь, если включена настройка optimize_functions_to_subcolumns,
поэтому json['a']['b'] читает путь a.b точно так же, как и json.a.b: в строке, где a содержит
скаляр, а не объект, пути a.b нет, и результатом будет NULL. Без этой оптимизации внешнее обращение
применяется к значению Dynamic выражения json['a'], и для такой строки действует
настройка dynamic_throw_on_type_mismatch.
Если запрошенный путь не был найден в данных, он будет заполнен значениями NULL:
Query
Response
Query
Response
a.b используется тип UInt32, как и было указано в объявлении типа JSON,
а для всех остальных подстолбцов используется тип Dynamic.
Подстолбцы типа Dynamic также можно читать, используя специальный синтаксис json.some.path.:TypeName:
Query
Response
Dynamic можно привести к любому типу данных. В этом случае будет сгенерировано исключение, если внутренний тип в Dynamic нельзя привести к запрошенному типу:
Query
Response
Query
Response
Чтобы эффективно читать подстолбцы из компактных частей MergeTree, убедитесь, что включена настройка MergeTree write_marks_for_substreams_in_compact_parts.
Чтение вложенных объектов JSON как подстолбцов
ТипJSON позволяет читать вложенные объекты как подстолбцы типа JSON с помощью специального синтаксиса json.^some.path:
Query
Response
Query
Response
Когда пути хранятся в базовом (
map) общих данных, чтение подстолбцов вложенных объектов может быть неэффективным, так как требует сканирования всей общей структуры данных. При сериализации общих данных map_with_buckets, advanced или advanced_chunked чтение подстолбцов из общих данных значительно оптимизировано.Чтение комбинированных подстолбцов JSON
ТипJSON поддерживает чтение пути в виде комбинированного подстолбца с использованием специального синтаксиса json.@some.path.
Комбинированный подстолбец для заданного пути возвращает:
- Литеральное значение, хранящееся по этому пути, как
Dynamic, если по этому пути есть литеральное значение. - Подобъект JSON по этому пути как
Dynamic, если по этому пути нет литерального значения, но есть вложенные подпути. NULL, если для этого пути не существует ни литерального значения, ни каких-либо подпутей.
json.a) и подстолбцу подобъекта (json.^a).
В следующем примере сравниваются все три типа подстолбцов для пути a:
Query
Response
Query
Response
- Строка 1:
aсодержит литерал42.json.aвозвращает его какDynamic(Int64),json.^aвозвращает пустой подобъект{}(уaнет вложенных ключей), аjson.@aвозвращает литерал42. - Строка 2:
aсодержит вложенный объект.json.aвозвращаетNULL(по этому пути нет литерального значения),json.^aвозвращает подобъект какJSON, аjson.@aтакже возвращает подобъект какDynamic(JSON). - Строка 3:
aполностью отсутствует. Иjson.a, иjson.@aвозвращаютNULL, аjson.^aвозвращает пустой объект{}.
Когда пути хранятся в базовых (
map) общих данных, чтение комбинированных подстолбцов может быть неэффективным, поскольку требует сканирования всех общих данных. При сериализации общих данных map_with_buckets, advanced или advanced_chunked чтение подстолбцов из общих данных значительно оптимизировано.Вывод типов для путей
При разбореJSON ClickHouse пытается определить наиболее подходящий тип данных для каждого JSON-пути.
Это работает так же, как автоматическое определение схемы,
и управляется теми же настройками:
- input_format_try_infer_dates
- input_format_try_infer_datetimes
- schema_inference_make_columns_nullable
- input_format_json_try_infer_numbers_from_strings
- input_format_json_infer_incomplete_types_as_strings
- input_format_json_read_numbers_as_strings
- input_format_json_read_bools_as_strings
- input_format_json_read_bools_as_numbers
- input_format_json_read_arrays_as_strings
- input_format_json_infer_array_of_dynamic_from_array_of_different_types
Query
Response
Query
Response
Query
Response
Query
Response
Обработка массивов объектов JSON
JSON-пути, содержащие массив объектов, разбираются как типArray(JSON) и записываются в столбец Dynamic для этого пути.
Чтобы прочитать массив объектов, его можно извлечь из столбца Dynamic как подстолбец:
Query
Response
Query
Response
max_dynamic_types/max_dynamic_paths для вложенного типа JSON были уменьшены по сравнению со значениями по умолчанию.
Это необходимо, чтобы число подстолбцов не росло бесконтрольно во вложенных массивах объектов JSON.
Давайте попробуем прочитать подстолбцы из вложенного столбца JSON:
Query
Response
Array(JSON), используя специальный синтаксис:
Query
Response
[] после пути указывает на уровень массива. Например, json.path[][] будет преобразован в json.path.:Array(Array(JSON))
Давайте проверим пути и типы внутри нашего Array(JSON):
Query
Response
Array(JSON):
Query
Response
JSON также можно читать подстолбцы подобъектов:
Query
Response
Обработка ключей JSON со значением NULL
В нашей реализации JSONnull и отсутствие значения считаются эквивалентными:
Query
Response
Обработка ключей JSON с точками
Внутри JSON-столбца все пути и значения хранятся в уплощённом виде. Это означает, что по умолчанию эти 2 объекта считаются одинаковыми:a.b и значение 42. При форматировании JSON мы всегда формируем вложенные объекты на основе частей пути, разделённых точкой:
Query
Response
{"a.b" : 42} теперь имеет вид {"a" : {"b" : 42}}.
Это ограничение также приводит к ошибке при разборе корректных объектов JSON, таких как этот:
Query
Response
25.8). В этом случае при парсинге все точки в ключах JSON будут
экранироваться как %2E, а при formatting преобразовываться обратно.
Query
Response
Query
Response
Query
Response
json.`a.b` эквивалентен подстолбцу json.a.b и не сможет прочитать путь с экранированной точкой:
Query
Response
SKIP/SKIP REGEX), в подсказке необходимо экранировать точки:
Query
Response
Query
Response
Чтение типа JSON из данных
Все текстовые форматы (JSONEachRow,
TSV,
CSV,
CustomSeparated,
Values и т. д.) поддерживают чтение данных типа JSON.
Примеры:
Query
Response
CSV/TSV/и т. д., JSON разбирается из строки, содержащей объект JSON:
Query
Response
Достижение предела динамических путей внутри JSON
Тип данныхJSON может хранить только ограниченное количество путей во внутреннем представлении в виде отдельных подстолбцов.
По умолчанию этот предел равен 1024, но его можно изменить в объявлении типа с помощью параметра max_dynamic_paths.
Когда предел достигнут, все новые пути, вставляемые в столбец JSON, будут храниться в единой общей структуре данных.
Такие пути по-прежнему можно читать как подстолбцы,
но это может быть менее эффективно (см. раздел об общей структуре данных).
Этот предел нужен, чтобы избежать появления огромного количества разных подстолбцов, из-за которых таблица может стать непригодной для использования.
Давайте посмотрим, что происходит, когда этот предел достигается, в нескольких разных сценариях.
Достижение лимита при парсинге данных
При парсинге объектовJSON из данных, когда для текущего блока данных достигается лимит,
все новые пути будут сохраняться в общей структуре данных. Можно использовать следующие две функции интроспекции: JSONDynamicPaths, JSONSharedDataPaths:
Query
Response
e и f.g лимит был достигнут,
и они были вставлены в общую структуру данных.
При слиянии частей данных в движках таблиц MergeTree
При слиянии нескольких частей данных в таблицеMergeTree столбец JSON в результирующей части данных может достичь лимита динамических путей
и не сможет хранить все пути из исходных частей в виде подстолбцов.
В этом случае ClickHouse определяет, какие пути останутся подстолбцами после слияния, а какие будут храниться в общей структуре данных.
В большинстве случаев ClickHouse старается сохранить пути, содержащие
наибольшее количество не NULL значений, а самые редкие пути переместить в общую структуру данных. Однако это зависит от реализации.
Рассмотрим пример такого слияния.
Сначала создадим таблицу со столбцом JSON, установим лимит динамических путей равным 3, а затем вставим значения с 5 различными путями:
Query
JSON будет содержать только один путь:
Query
Response
Query
Response
a, b и c, а пути d и e переместил в общую структуру данных.
Общая структура данных
Как описано в предыдущем разделе, при достижении ограниченияmax_dynamic_paths все новые пути сохраняются в одной общей структуре данных.
В этом разделе мы подробнее рассмотрим общую структуру данных и то, как из неё читаются подстолбцы путей.
Подробные сведения о функциях, используемых для анализа содержимого JSON-столбца, см. в разделе “функции интроспекции”.
Общая структура данных в памяти
В памяти общая структура данных — это просто подстолбец типаMap(String, String), который хранит соответствие между JSON-путём в плоском виде и значением, закодированным в бинарном виде.
Чтобы извлечь из него подстолбец для пути, мы просто проходим по всем строкам в этом столбце Map и пытаемся найти запрошенный путь и его значения.
Общая структура данных в частях MergeTree
В таблицах MergeTree данные хранятся в частях данных, в которых всё записывается на диск (локальный или удалённый). При этом данные на диске могут храниться иначе, чем в памяти. Сейчас в частях данных MergeTree используются 4 разных варианта сериализации общей структуры данных:map, map_with_buckets,
advanced и advanced_chunked.
Версия сериализации определяется
настройками MergeTree object_shared_data_serialization_version
и object_shared_data_serialization_version_for_zero_level_parts
(часть нулевого уровня — это часть, создаваемая при вставке данных в таблицу; при слиянии части получают более высокий уровень).
Примечание: изменение сериализации общей структуры данных поддерживается только
для v3 object serialization version
Map
В версии сериализацииmap общие данные сериализуются в виде одного столбца типа Map(String, String), так же, как они хранятся в
памяти. Чтобы прочитать подстолбец по пути из этого типа сериализации, ClickHouse считывает весь столбец Map и
извлекает нужный путь в памяти.
Эта сериализация эффективна для записи данных и чтения всего JSON-столбца, но неэффективна для чтения подстолбцов по путям.
Map с бакетами
В версии сериализацииmap_with_buckets общие данные сериализуются как N столбцов («бакетов») типа Map(String, String).
Каждый такой бакет содержит только подмножество путей. Чтобы прочитать подстолбец по пути из этого типа сериализации, ClickHouse
считывает весь столбец Map из одного бакета и уже в памяти извлекает запрошенный путь.
Эта сериализация менее эффективна для записи данных и чтения всего JSON-столбца, но более эффективна для чтения подстолбцов по путям,
поскольку считывает данные только из нужных бакетов.
Количество бакетов N задаётся настройками MergeTree object_shared_data_buckets_for_compact_part (по умолчанию 8)
и object_shared_data_buckets_for_wide_part (по умолчанию 32).
Максимально допустимое значение для обеих настроек — 256.
Продвинутая
В версии сериализацииadvanced общие данные сериализуются в специальную структуру данных, которая обеспечивает максимальную производительность
чтения подстолбцов по путям за счёт хранения дополнительной информации, позволяющей читать только данные запрошенных путей.
Эта сериализация также поддерживает бакеты, поэтому каждый бакет содержит только подмножество путей.
Эта сериализация довольно неэффективна для записи данных (поэтому её не рекомендуется использовать для частей нулевого уровня), чтение всего JSON-столбца немного менее эффективно по сравнению с сериализацией map, но для чтения подстолбцов по путям она очень эффективна.
Примечание: из-за хранения дополнительной информации внутри структуры данных объём данных на диске при использовании этой сериализации больше по сравнению с
сериализациями map и map_with_buckets.
Более подробный обзор новых сериализаций общих данных и подробности реализации см. в записи блога.
Продвинутая фрагментированная
Сериализацияadvanced_chunked аналогична advanced, но поддерживает разделение строк на более мелкие фрагменты при сериализации.
Это снижает пиковое потребление памяти при слиянии JSON-столбцов со множеством уникальных путей, поскольку одновременно
требуется материализовать данные лишь одного фрагмента, а не всего диапазона строк.
Размер фрагмента задаётся настройкой MergeTree object_shared_data_target_chunk_rows (по умолчанию 8192).
Это не жёсткое ограничение: если последний фрагмент будет меньше половины целевого размера, он объединяется с предыдущим фрагментом,
поэтому фактический размер фрагментов находится в диапазоне от target/2 до 1.5 * target.
Управление количеством динамических путей внутри JSON в частях данных MergeTree
Основной способ задать ограничение на динамические пути в JSON — использовать параметрmax_dynamic_paths в объявлении типа JSON.
Однако изменение max_dynamic_paths для существующих столбцов требует выполнения ALTER TABLE <table> MODIFY COLUMN <column> JSON(max_dynamic_paths=K), что запустит фоновую мутацию, переписывающую все существующие части.
Такая мутация может быть очень ресурсоемкой и может влиять на производительность сервера до ее завершения. Чтобы избежать этого, можно использовать следующие 3 настройки, которые позволяют изменить ограничение на динамические пути в таблицах семейства MergeTree для новых частей данных:
merge_max_dynamic_subcolumns_in_wide_part- настройка MergeTree, которая ограничивает количество динамических подстолбцов для каждого JSON-столбца при слиянии в часть данных Wide.merge_max_dynamic_subcolumns_in_compact_part- настройка MergeTree, которая ограничивает количество динамических подстолбцов для каждого JSON-столбца при слиянии в часть данных Compact.max_dynamic_subcolumns_in_json_type_parsing- настройка сеанса, которая ограничивает количество динамических подстолбцов для каждого JSON-столбца при разборе JSON-данных в JSON-столбец.
max_dynamic_paths, даже если значения описанных настроек выше.
Функции интроспекции
Есть несколько функций, которые помогают исследовать содержимое JSON-столбца:JSONAllPathsJSONAllPathsWithTypesJSONAllValuesJSONDynamicPathsJSONDynamicPathsWithTypesJSONSharedDataPathsJSONSharedDataPathsWithTypesdistinctDynamicTypesdistinctJSONPaths and distinctJSONPathsAndTypes
2020-01-01:
Query
Response
Query
Response
ALTER MODIFY COLUMN в тип JSON
Существующую таблицу можно изменить, поменяв тип столбца на новый типJSON. В настоящее время поддерживается только ALTER из типа String.
Пример
Query
Response
Ленивые подсказки типов (бета)
Эта возможность находится в стадии бета, и для нее необходимо включить настройку
enable_json_lazy_type_hints.ALTER TABLE ... MODIFY COLUMN, ClickHouse обычно переписывает все части данных, чтобы материализовать новые подсказки типов. Для таблиц с большими объемами исторических данных (сотни терабайт) это может быть чрезвычайно затратно.
Ленивые подсказки типов позволяют добавлять подсказки типов как операцию, затрагивающую только метаданные, без переписывания существующих данных:
- Старые части: подсказки типов применяются во время выполнения запроса через приведение из
Dynamicк указанному типу - Новые части: подсказки типов материализуются во время операций
INSERT - Слияния: подсказки типов материализуются при слиянии частей
Включение ленивых подсказок типов
Пример
Query
Response
Проверка отсутствия мутации
Вы можете убедиться, чтоALTER завершился без мутации, проверив таблицу system.mutations:
Материализация подсказок типов
Чтобы материализовать подсказки типов в уже существующих данных, можно:- Дождаться фоновых слияний: ClickHouse автоматически материализует подсказки типов при слиянии частей
- Принудительно запустить слияние: используйте
OPTIMIZE TABLE test_lazy FINAL, чтобы сразу слить все части - Переписать части: используйте
ALTER TABLE test_lazy REWRITE PARTS, чтобы переписать части с новыми метаданными
Ограничения
- Преобразование типов при выполнении запроса может приводить к существенным накладным расходам по производительности по сравнению с заранее материализованными типами, особенно для крупных объектов JSON
- Эта возможность работает только при изменении
typed_paths(подсказок типов); другие параметры JSON, такие какmax_dynamic_paths,SKIPилиSKIP REGEXP, по-прежнему требуют мутаций
-
Изменение подсказки типа (или удаление типизированного пути) не является операцией только с метаданными и отклоняется, если затронутый подстолбец используется в структуре с позиционным хранением:
- в первичном ключе/ключе сортировки или ключе партиционирования — изменение запрещено, поскольку первичный индекс / значения партиции на диске нельзя перестроить с помощью
ALTER, изменяющего только метаданные (как и для любого другого ключевого столбца); - в явном индексе пропуска данных — сначала удалите индекс или отключите
enable_json_lazy_type_hints, чтобы выполнить изменение как полную мутацию, перестраивающую индекс. - в проекции, ключ сортировки (
ORDER BY) которой считывает подстолбец — сначала удалите проекцию, посколькуALTER, изменяющий только метаданные, не может перестроить первичный индекс проекции.
- в первичном ключе/ключе сортировки или ключе партиционирования — изменение запрещено, поскольку первичный индекс / значения партиции на диске нельзя перестроить с помощью
Сравнение значений типа JSON
Объекты JSON сравниваются аналогично значениям типа Map. Например:Query
Response
Variant.
Индексы пропуска данных для JSON
Индексы пропуска данных можно использовать сJSON-столбцами тремя способами:
- Индексы для конкретных подстолбцов — создайте стандартный индекс пропуска данных для известного JSON-пути, как и для обычного столбца. В этом случае индексируются значения по этому пути.
- Индексы на основе путей с
JSONAllPaths— индексируйте набор путей, присутствующих в каждой грануле, чтобы пропускать гранулы, в которых не может содержаться запрашиваемый путь. - Индексы на основе значений с
JSONAllValues— индексируйте все значения по всем JSON-путям с помощью текстового индекса, чтобы ускорить полнотекстовый поиск по любому подстолбцу JSON с помощью одного индекса.
Индексы для отдельных подстолбцов
Вы можете создать индекс пропуска данных для любого подстолбца JSON, используя тот же синтаксис, что и для обычных столбцов. Поддерживается любой тип индекса (minmax, set, bloom_filter, tokenbf_v1, ngrambf_v1 и т. д.).
Есть два способа указать подстолбец JSON в выражении индекса:
- Типизированный путь, объявленный в подсказке типа JSON, — прямой доступ по имени:
json.a. - Динамический путь с явным приведением типа — используйте синтаксис приведения
:::json.b::String.
json.a || json.b::String.
Пример
Query
minmax на типизированном подстолбце data.sensor_id сужает область сканирования до подходящих гранул:
Query
Response
bloom_filter для приведённого подстолбца data.location::String также работает:
Query
Response
Индексы по путям с JSONAllPaths
Индексы пропуска данных также можно создавать дляJSON-столбцов с помощью функции JSONAllPaths.
Это работает так же, как создание индексов пропуска данных для столбцов Map через mapKeys: индекс хранит набор JSON-путей, присутствующих в каждой грануле, и использует его, чтобы пропускать гранулы, которые не могут содержать запрашиваемый путь.
Поддерживаемые типы индексов
JSONAllPaths можно использовать со следующими типами индексов пропуска данных:
bloom_filter— поддерживаетequals,inиIS NOT NULL.tokenbf_v1— поддерживаетequalsиIS NOT NULL.ngrambf_v1— поддерживаетequalsиIS NOT NULL.text(обратный индекс) — поддерживаетequals,inиIS NOT NULL.
Пример
Query
EXPLAIN indexes = 1, чтобы проверить, что индекс пропуска данных действительно используется. Если путь существует только в одной части данных, индекс пропускает другую часть:
Query
Response
Query
Response
IS NOT NULL также использует индекс — он пропускает гранулы, в которых путь отсутствует (так как в этом случае значение было бы NULL):
Query
Response
Как это работает
ВыражениеJSONAllPaths(json_column) возвращает Array(String), содержащий все пути, присутствующие в значении JSON.
Индекс пропуска данных хранит строки этих путей в своей структуре данных (фильтр Блума или обратный индекс).
Когда в запросе используется фильтрация по json.some.path, индекс проверяет для каждой гранулы, есть ли в нём строка "some.path", и пропускает гранулы, где она отсутствует.
С индексом сопоставляется только обычный доступ по пути, при необходимости с подсказкой типа или приведением типов (json.a.b, json.a.b.:Int64, json.a.b::String).
Фильтры по подстолбцу подобъекта (json.^a) и по комбинированному подстолбцу literal+sub-object (json.@`a) не используют индекс: эти подстолбцы не равны NULL, если существует какой-либо вложенный путь a, поэтому наличие самого пути a в JSONAllPaths не является эквивалентным условием.
Безопасность при отсутствии путей
Если путь JSON отсутствует в грануле, подстолбец принимает значение:NULLдля типаDynamic(например,json.path) и подстолбцов типаNullable(например,json.path.:Int64) — сравнения сNULLвсегда возвращают false, поэтому пропуск безопасен.- Значение по умолчанию этого типа для выражений CAST без
Nullable(например,json.path::Int64даёт0, если путь отсутствует) — пропуск безопасен, только если сравниваемое значение отличается от значения по умолчанию. Индекс автоматически учитывает это различие.
Полнотекстовый поиск с JSONAllValues
Текстовые индексы можно использовать для ускорения полнотекстового поиска по JSON-столбцам с помощью функцииJSONAllValues.
JSONAllValues возвращает все значения из JSON-столбца в виде Array(String), который можно проиндексировать текстовым индексом.
Один индекс на JSONAllValues(json_column) охватывает все JSON-пути, позволяя выполнять полнотекстовый поиск по любому подстолбцу без создания отдельных индексов для каждого пути.
Подробнее и примеры см. в разделе Индексы на основе значений с JSONAllValues в документации по текстовым индексам.
Советы по более эффективному использованию типа JSON
Прежде чем создаватьJSON-столбец и загружать в него данные, обратите внимание на следующие рекомендации:
- Изучите свои данные и укажите как можно больше подсказок для путей с типами. Это сделает хранение и чтение данных гораздо эффективнее.
- Продумайте, какие пути вам понадобятся, а какие — никогда. Укажите пути, которые вам не нужны, в разделе
SKIP, а при необходимости — и в разделеSKIP REGEXP. Это повысит эффективность хранения. - Не задавайте параметру
max_dynamic_pathsслишком большие значения, так как это может снизить эффективность хранения и чтения. Хотя это сильно зависит от параметров системы, таких как память, CPU и т. д., в качестве общего практического правила не стоит устанавливатьmax_dynamic_pathsвыше 10 000 для хранения в локальной файловой системе и 1024 — для хранения в удалённой файловой системе.