Перейти к основному содержанию
В этом руководстве описаны распространённые способы работы с JSON-данными, реплицированными из MongoDB в ClickHouse через ClickPipes. Предположим, мы создали коллекцию t1 в MongoDB для отслеживания заказов клиентов:
Коннектор MongoDB CDC реплицирует документы MongoDB в ClickHouse, используя встроенный тип данных JSON. В реплицируемой таблице t1 в ClickHouse будет содержаться следующая строка:

Схема таблицы

Для реплицируемых таблиц используется следующая стандартная схема:
  • _id: Первичный ключ из MongoDB
  • doc: Документ MongoDB, реплицированный в типе данных JSON
  • _peerdb_synced_at: Указывает, когда строка была синхронизирована в последний раз
  • _peerdb_version: Отслеживает версию строки; увеличивается при обновлении или удалении строки
  • _peerdb_is_deleted: Указывает, удалена ли строка

Движок таблицы ReplacingMergeTree

ClickPipes сопоставляет коллекции MongoDB с ClickHouse с помощью семейства движков таблиц ReplacingMergeTree. В этом движке обновления представляются как вставки более новой версии (_peerdb_version) документа для данного первичного ключа (_id), что позволяет эффективно обрабатывать обновления, замены и удаления как версионированные вставки. ReplacingMergeTree удаляет дубликаты асинхронно в фоновом режиме. Чтобы гарантировать отсутствие дубликатов для одной и той же строки, используйте модификатор FINAL. Например:

Обработка удалений

Удаления из MongoDB передаются как новые строки, помеченные как удалённые в столбце _peerdb_is_deleted. Обычно такие строки исключают с помощью фильтра в запросах:
Вы также можете создать политику на уровне строк, чтобы автоматически исключать удалённые строки, вместо того чтобы указывать фильтр в каждом запросе:

Запросы к данным JSON

Вы можете напрямую обращаться к полям JSON, используя точечную нотацию:
Query
Result
При запросе полей вложенных объектов с использованием точечной нотации обязательно добавляйте оператор ^:
Query
Result

Тип Dynamic

В ClickHouse каждое поле в JSON имеет тип Dynamic. Тип Dynamic позволяет ClickHouse хранить значения любых типов, не зная тип заранее. Это можно проверить с помощью функции toTypeName:
Query
Result
Чтобы узнать фактические типы данных поля, можно воспользоваться функцией dynamicType. Обратите внимание: у одного и того же имени поля в разных строках могут быть разные типы данных:
Query
Result
Обычные функции работают с типом Dynamic так же, как и с обычными столбцами: Пример 1: Парсинг даты
Query
Result
Пример 2: Условная логика
Query
Result
Пример 3: операции с Array
Query
Result

Приведение типов полей

Агрегатные функции в ClickHouse не работают с типом Dynamic напрямую. Например, если попытаться применить функцию sum непосредственно к типу Dynamic, возникнет следующая ошибка:
Чтобы использовать агрегатные функции, приведите поле к соответствующему типу с помощью функции CAST или синтаксиса :::
Query
Result
Приведение из типа Dynamic к базовому типу данных (определяемому с помощью dynamicType) выполняется очень быстро, поскольку ClickHouse уже хранит значение внутри в этом базовом типе.

Преобразование JSON в плоский вид

Обычное представление

Вы можете создавать обычные представления над JSON-таблицей, чтобы инкапсулировать логику разворачивания, приведения типов и преобразования, а затем запрашивать данные как в реляционной таблице. Обычные представления легковесны, поскольку хранят только сам запрос, а не исходные данные. Например:
У этого представления будет следующая схема:
Теперь можно выполнять запросы к представлению так же, как к денормализованной таблице:

Refreshable materialized view

Вы можете создавать Refreshable Materialized Views, которые позволяют по расписанию выполнять запрос для дедупликации строк и сохранять результаты в плоскую целевую таблицу. При каждом обновлении по расписанию целевая таблица заменяется последними результатами запроса. Ключевое преимущество этого метода в том, что запрос с ключевым словом FINAL выполняется только один раз — во время обновления, поэтому в последующих запросах к целевой таблице использовать FINAL уже не нужно. Недостаток в том, что данные в целевой таблице остаются актуальными лишь до степени, соответствующей времени последнего обновления. Во многих сценариях интервалы обновления от нескольких минут до нескольких часов обеспечивают хороший баланс между актуальностью данных и производительностью запросов.
Теперь вы можете обращаться к таблице flattened_t1 напрямую, без модификатора FINAL:

Incremental materialized view

Если вам нужен доступ к развёрнутым столбцам в реальном времени, вы можете создать Incremental Materialized Views. Если в вашей таблице часто происходят обновления, не рекомендуется использовать модификатор FINAL в materialized view, так как каждое обновление будет запускать слияние. Вместо этого дедупликацию данных можно выполнять во время выполнения запроса, создав обычное представление поверх materialized view.
Теперь вы можете выполнить запрос к представлению flattened_t1_final следующим образом:
Последнее изменение 3 июля 2026 г.