chore(repo): заложен репозиторий v2 — контракт, спека, исследование
- Зачем:
- спека «Боевой реализм стенда» исполняется в новом репозитории:
предшественник замораживается как стабильный учебный стенд,
v2 стартует пустым и переносит только нужное
- Что:
- README: что это, статус «строится по спеке», ссылки на спеку и на
репозиторий-предшественник
- AGENTS.md написан заново, а не скопирован: язык, uv, обязательная
проверка API через MCP Context7, контракт трекера Gitea (спека —
источник истины, корневой issue тонкий), метки триажа, новые доки в docs/
- .gitignore: Python и uv, .env, секреты, IDE, логи
- docs/specs/2026-07-30-stand-v2-realism.md перенесена из v1; содержание
не менялось, поправлены только ссылки: добавлена строка о переезде,
ссылка на generator-realism.md переведена на абсолютный URL v1
- docs/research/2026-07-26-yandex-clickstream-format.md перенесено:
источник истины по формату широкого события
- лицензии у предшественника нет, переносить нечего
- Проверка:
- git show --stat: 5 файлов
- относительные ссылки спеки ведут на существующие файлы репозитория
This commit is contained in:
@@ -0,0 +1,723 @@
|
||||
# Формат кликстрима Яндекса: что копировать стенду
|
||||
|
||||
Status: Research
|
||||
Дата: 2026-07-26
|
||||
Тикет: [#27](https://github.com/dementev-dev/clickstream-ch-kafka-superset-demo/issues/27)
|
||||
|
||||
## Зачем это исследование
|
||||
|
||||
Владелец стенда выбирает целевую модель данных. Сейчас событие разрезано на
|
||||
четыре топика (`browser`, `location`, `device`, `geo`), которые склеиваются по
|
||||
`event_id` и `click_id`. Вопрос: переходить ли на одно широкое событие и по
|
||||
какому образцу его строить.
|
||||
|
||||
Образец выбран — Яндекс. В России Метрика и AppMetrica — основной источник
|
||||
кликстрима, и менти должен узнать формат, когда столкнётся с ним на работе.
|
||||
|
||||
Всё ниже — по документации Яндекса, ClickHouse, Snowplow, Segment и Amplitude.
|
||||
Где источник найти не удалось, это написано прямо.
|
||||
|
||||
## Коротко: ответы на главные вопросы
|
||||
|
||||
**Форма — плоское ядро с массивами, не вложенный JSON.** У Яндекса нет
|
||||
вложенных объектов вроде `context` или `properties`. Есть примерно 140 плоских
|
||||
колонок на хит, и всё, что бывает «много раз в одном событии» (цели, товары,
|
||||
покупки, свои параметры), лежит в **параллельных массивах**: `productID`,
|
||||
`productName`, `productPrice` — три отдельных массива одной длины, а не массив
|
||||
объектов. Именно эту форму стенду и стоит копировать.
|
||||
|
||||
**Доставка — батч для всех и поток для платных.** Обычный путь (Logs API) —
|
||||
батч: запрос готовится, потом скачивается TSV-файл. Данные за текущий день
|
||||
недоступны. В тарифе «Метрика Про» есть поток в управляемый ClickHouse с
|
||||
задержкой до 15 минут. Kafka в этой картине нет ни в одном официальном
|
||||
варианте.
|
||||
|
||||
**Kafka на стенде — учебная замена, и так это и надо называть.** Подробный
|
||||
разбор — в разделе «Батч или поток».
|
||||
|
||||
Главные находки:
|
||||
|
||||
1. Метрика отдаёт **две разные сущности**: хиты (`hits`, просмотры страниц) и
|
||||
визиты (`visits`, сессии). Визит — уже свёрнутая сессия с массивами внутри.
|
||||
2. **56 полей хитов — массивы** (по подсчёту на странице полей Logs API).
|
||||
Массивы — основной способ Яндекса выразить «много значений в одном событии».
|
||||
3. **User agent строкой Метрика не отдаёт.** Отдаются уже разобранные поля:
|
||||
`browser`, `browserMajorVersion`, `operatingSystem`, `deviceCategory`.
|
||||
Поле `browser_user_agent` на стенде — наша выдумка, у Яндекса аналога нет.
|
||||
4. **Координат в выгрузке Метрики нет.** Гео — это `regionCountry`,
|
||||
`regionCity` и числовые `regionCountryID`, `regionCityID`. Наши
|
||||
`geo_latitude` и `geo_longitude` тоже без аналога.
|
||||
5. **Метки времени: серверная одна.** В хитовой выгрузке в облако есть
|
||||
`UTCEventTime` и смещение часового пояса клиента `ClientTimeZone` (в
|
||||
минутах). Отдельной клиентской метки времени нет. Разделение «время у
|
||||
клиента» и «время приёма на сервере» есть у AppMetrica
|
||||
(`event_datetime` против `event_receive_datetime`), не у Метрики.
|
||||
6. **Поток даёт версии одной записи.** В потоковой выгрузке есть колонки `Sign`
|
||||
(Int8) и `HitVersion` / `VisitVersion`. Старая версия приходит со `Sign =
|
||||
-1`, новая с `Sign = 1`; складывать надо через `sum(Sign)`. Это ровно та же
|
||||
механика, что у движка `CollapsingMergeTree` в ClickHouse.
|
||||
7. **Ecommerce и выручка в выгрузке есть, но плоско.** Сумма заказа —
|
||||
`purchaseRevenue` типа `Array(Float64)`, валюта — `purchaseCurrency` типа
|
||||
`Array(String)`. Плюс отдельно лежит поле `ecommerce` типа `String` — сырой
|
||||
JSON события ecommerce.
|
||||
|
||||
## 1. Logs API Метрики: состав данных
|
||||
|
||||
Источники: [список полей — хиты](https://yandex.ru/dev/metrika/ru/logs/fields/hits),
|
||||
[список полей — визиты](https://yandex.ru/dev/metrika/ru/logs/fields/visits),
|
||||
[введение в Logs API](https://yandex.ru/dev/metrika/ru/logs/).
|
||||
|
||||
### Две сущности вместо одной
|
||||
|
||||
- **Хит (`hits`)** — одно действие: просмотр страницы, клик по ссылке, скачивание
|
||||
файла. Имена полей начинаются с `ym:pv:`.
|
||||
- **Визит (`visits`)** — сессия целиком. Имена полей начинаются с `ym:s:`.
|
||||
Внутри визита лежит массив идентификаторов его хитов: `ym:s:watchIDs` типа
|
||||
`Array(UInt64)`, не более 500 просмотров.
|
||||
|
||||
Это важно для стенда: у Яндекса «широкое событие» — это хит, а сессия —
|
||||
отдельная широкая запись, собранная Яндексом на своей стороне. У нас сессии
|
||||
считаются в DDS/DM; у Яндекса они приходят готовыми.
|
||||
|
||||
### Идентификаторы
|
||||
|
||||
| Поле | Тип | Что это |
|
||||
|---|---|---|
|
||||
| `ym:pv:watchID` | UInt64 | Идентификатор хита |
|
||||
| `ym:pv:pageViewID` | UInt32 | Идентификатор просмотра страницы |
|
||||
| `ym:pv:visitID` | UInt64 | Идентификатор визита (в хитах доступен с 10.10.2025) |
|
||||
| `ym:pv:counterID` | UInt32 | Номер счётчика (то есть сайта) |
|
||||
| `ym:pv:clientID` | UInt64 | Анонимный идентификатор посетителя через свою cookie |
|
||||
| `ym:pv:counterUserIDHash` | UInt64 | Идентификатор посетителя для подсчёта уникальных |
|
||||
| `ym:s:visitID`, `ym:s:clientID`, `ym:s:counterUserIDHash` | те же типы | То же на уровне визита |
|
||||
|
||||
Все идентификаторы — **числа**, не UUID.
|
||||
|
||||
Про `UserID` — свой идентификатор пользователя со стороны сайта. По справке
|
||||
Метрики он передаётся методом `setUserID` и связывается с `ClientID`, если
|
||||
метод вызвали во время сессии
|
||||
([setUserID](https://yandex.com/support/metrica/en/objects/set-user-id.html)).
|
||||
Поля `UserID` **в списке выгружаемых полей Logs API найти не удалось** — ни в
|
||||
хитах, ни в визитах. В выгрузке хитов в облако его тоже нет. Считаем: свой
|
||||
идентификатор пользователя в кликстриме Метрики напрямую не выдаётся.
|
||||
|
||||
Про рекламные метки:
|
||||
|
||||
- `ym:pv:hasGCLID` (UInt8) и `ym:pv:GCLID` (String) — метка клика Google.
|
||||
- `ym:pv:hasSBCLID` (UInt8) и `ym:pv:SBCLID` (String) — метка SBCLID.
|
||||
- **`YCLID` в списке полей Logs API не найден.** Он есть в примерном датасете
|
||||
ClickHouse как колонка `YCLID UInt64` (см. раздел 5) и упоминается в справке
|
||||
Метрики как идентификатор клика по объявлению Яндекс Директа. Вывод: в
|
||||
выгрузке Logs API поле `yclid` не подтверждено; в схеме ClickHouse оно есть.
|
||||
|
||||
### Метки времени и часовой пояс
|
||||
|
||||
| Поле | Тип | Что это |
|
||||
|---|---|---|
|
||||
| `ym:pv:date` | Date | Дата события |
|
||||
| `ym:pv:dateTime` | DateTime | Дата и время события **в часовом поясе счётчика** |
|
||||
| `ym:pv:clientTimeZone` | Int16 | Смещение часового пояса посетителя от UTC **в минутах** |
|
||||
| `ym:s:dateTime` | DateTime | Время визита в часовом поясе счётчика |
|
||||
| `ym:s:dateTimeUTC` | DateTime | Время визита в UTC+3 |
|
||||
|
||||
Две вещи, которые стоит запомнить:
|
||||
|
||||
- Часовой пояс — не UTC по умолчанию. У хита это «пояс счётчика», у визита есть
|
||||
и вторая колонка в UTC+3 (то есть по московскому времени, а не по нулевому
|
||||
меридиану).
|
||||
- Клиентское время события отдельным полем не приходит. Приходит только
|
||||
**смещение пояса клиента**. То есть «две метки времени, клиентская и
|
||||
серверная» — это про AppMetrica и про западные трекеры, но не про Метрику.
|
||||
|
||||
### Массивы
|
||||
|
||||
Массивов очень много. Страница полей хитов помечает **56 полей как массивы**.
|
||||
Основные группы:
|
||||
|
||||
- **Цели:** `ym:pv:goalsID` — `Array(UInt32)`. У визита целая группа
|
||||
параллельных массивов: `ym:s:goalsID`, `ym:s:goalsSerialNumber`,
|
||||
`ym:s:goalsDateTime`, `ym:s:goalsPrice`, `ym:s:goalsOrder`,
|
||||
`ym:s:goalsCurrency`.
|
||||
- **Свои параметры:** `ym:pv:parsedParamsKey1` … `parsedParamsKey10`, каждый —
|
||||
`Array(String)`. Это десять уровней вложенности, разложенные по десяти
|
||||
массивам. Плюс поле `ym:pv:params` типа `String` — исходный JSON параметров.
|
||||
- **Покупки:** `ym:pv:purchaseID` `Array(String)`, `ym:pv:purchaseRevenue`
|
||||
`Array(Float64)`, `ym:pv:purchaseCurrency` `Array(String)` и другие (в хитах
|
||||
доступны с 19.06.2025).
|
||||
- **Товары:** `ym:pv:productID`, `productName`, `productBrand`,
|
||||
`productCategory`, `productCategoryLevel1`…`Level5`, `productPrice`
|
||||
`Array(Int64)`, `productQuantity` `Array(UInt64)`, `productEventType`
|
||||
`Array(String)` со значениями `view_item_list`, `click`, `detail`, `add`,
|
||||
`purchase`, `remove`.
|
||||
- **Промоакции:** `ym:pv:promotionID`, `promotionName`, `promotionCreative`,
|
||||
`promotionEventType`.
|
||||
|
||||
У визита к этому добавляются ещё три больших блока массивов:
|
||||
`ym:s:purchasedProduct*` (что купили), `ym:s:impressions*` (что показали) и
|
||||
`ym:s:offlineCall*` (звонки).
|
||||
|
||||
Ключевое наблюдение: **это параллельные массивы, а не массив объектов**. Третий
|
||||
товар в событии — это третий элемент в каждом из массивов `productID`,
|
||||
`productName`, `productPrice`. Собирается такое в ClickHouse через `ARRAY JOIN`.
|
||||
|
||||
### Что ещё есть в хите (короткий список категорий)
|
||||
|
||||
- Страница: `ym:pv:URL`, `ym:pv:referer`, `ym:pv:title`, `ym:pv:pageCharset`.
|
||||
- Атрибуция: `UTMSource`, `UTMMedium`, `UTMCampaign`, `UTMContent`, `UTMTerm`;
|
||||
`lastTrafficSource`, `lastSearchEngineRoot`, `lastSearchEngine`,
|
||||
`lastAdvEngine`, `lastSocialNetwork`; четыре поля Openstat; `ym:pv:from`.
|
||||
- Браузер: `browser`, `browserMajorVersion`, `browserMinorVersion`,
|
||||
`browserEngine` и четыре части его версии, `browserLanguage`,
|
||||
`browserCountry`, `cookieEnabled`, `javascriptEnabled`.
|
||||
- Устройство и экран: `deviceCategory` (1 = десктоп, 2 = телефон, 3 = планшет,
|
||||
4 = TV), `mobilePhone`, `mobilePhoneModel`, `operatingSystem`,
|
||||
`operatingSystemRoot`, `screenWidth`, `screenHeight`, `physicalScreenWidth`,
|
||||
`physicalScreenHeight`, `windowClientWidth`, `windowClientHeight`,
|
||||
`screenColors`, `screenFormat`, `screenOrientation`.
|
||||
- Гео и сеть: `ipAddress`, `regionCountry` (код ISO), `regionCity` (название
|
||||
по-английски), `regionCountryID`, `regionCityID`.
|
||||
- Признаки: `isPageView`, `isTurboPage`, `iFrame`, `link`, `download`,
|
||||
`notBounce`, `artificial`, `httpError`.
|
||||
|
||||
### Ограничения выгрузки
|
||||
|
||||
Со страницы [введения в Logs API](https://yandex.ru/dev/metrika/ru/logs/):
|
||||
|
||||
- Данные за **текущий день недоступны** — они могут быть неполными.
|
||||
- Данные «доформировываются» примерно **до 3 дней**; запрашивать рекомендуют
|
||||
начиная с предыдущих дней.
|
||||
- Максимальный период одного запроса — **1 год**.
|
||||
- Параметр со списком полей — **не более 3000 символов**.
|
||||
- Общая квота на объём подготовленных логов — **10 ГБ**. Подготовленные файлы
|
||||
надо регулярно удалять, иначе квота кончится. Квоту расширяет тариф
|
||||
«Метрика Про».
|
||||
- Результат Logs API может расходиться с интерфейсом Метрики из-за разных
|
||||
алгоритмов обработки и округления чисел с плавающей точкой.
|
||||
|
||||
Ограничение «не более 1 ГБ на файл» встречается в поиске по документации
|
||||
Метрики, но дословно подтвердить его на официальной странице ограничений не
|
||||
удалось — **не подтверждено**.
|
||||
|
||||
Порядок работы (по официальным описаниям API):
|
||||
|
||||
1. `POST /management/v1/counter/{counterId}/logrequests` — создать запрос.
|
||||
2. `GET /management/v1/counter/{counterId}/logrequest/{requestId}` — проверить
|
||||
статус; статус `processed` означает, что лог готов.
|
||||
3. `GET .../logrequest/{requestId}/part/{partNumber}/download` — скачать
|
||||
часть.
|
||||
|
||||
Формат выгрузки — **TSV**. Дословно из официального блога Метрики: «Сырые
|
||||
данные передаются в стандартном формате tsv»
|
||||
([блог Метрики про Logs API](https://yandex.ru/blog/metrika/vygruzhayte-syrye-dannye-iz-metriki-cherez-logs-api)).
|
||||
Там же прямо сказано, что типовой приёмник таких данных — ClickHouse.
|
||||
|
||||
## 2. Батч или поток
|
||||
|
||||
Коротко: **у Метрики есть оба пути, но Kafka нет ни в одном.**
|
||||
|
||||
### Путь 1. Logs API — батч
|
||||
|
||||
Запрос готовится, потом скачивается TSV-файл частями. Текущий день недоступен.
|
||||
Это не поток ни в каком смысле: минимальная задержка — сутки.
|
||||
|
||||
### Путь 2. Data Streaming в Yandex Cloud — поток, но не Kafka
|
||||
|
||||
Источник: [Data Streaming (интеграция с Yandex
|
||||
Cloud)](https://yandex.ru/support/metrica/ru/uploading-data/cloud), [как
|
||||
работать с данными](https://yandex.ru/support/metrica/ru/pro/data-work),
|
||||
[учебник Yandex
|
||||
Cloud](https://yandex.cloud/ru/docs/tutorials/dataplatform/metrika-to-clickhouse).
|
||||
|
||||
Что там есть:
|
||||
|
||||
- Неагрегированные данные Метрики попадают в **свой управляемый
|
||||
ClickHouse-кластер** в Yandex Cloud.
|
||||
- Задержка от события до записи в ClickHouse — **до 15 минут**.
|
||||
- Перенос делает **Yandex Data Transfer**, тип трансфера — «Репликация».
|
||||
- Хиты и визиты переносятся отдельными таблицами.
|
||||
- Историю до создания коннектора эта версия не переносит. Если трансфер
|
||||
выключить и включить, данные за простой потеряются.
|
||||
- Нужен тариф **«Метрика Про»**.
|
||||
- Визит меняется по мере поступления новых событий, поэтому в выгрузке лежат
|
||||
**разные версии одного визита**. Разбираются они через `Sign`: старая версия
|
||||
приходит со `Sign = -1`, новая со `Sign = 1`, считать надо через `sum(Sign)`
|
||||
в `GROUP BY`. Можно использовать модификатор `FINAL`, но он медленнее.
|
||||
|
||||
Приёмник здесь — ClickHouse напрямую. **Экспорт кликстрима Метрики в Object
|
||||
Storage или в Yandex Data Streams (сервис с Kafka-совместимым интерфейсом)
|
||||
официальной документацией не подтверждён.**
|
||||
|
||||
### Путь 3. AppMetrica Data Stream — пятиминутные окна
|
||||
|
||||
Источник: [Data Stream API,
|
||||
описание](https://appmetrica.yandex.ru/docs/ru/mobile-api/datastream/about).
|
||||
Поток представлен последовательностью **пятиминутных окон**, каждое окно
|
||||
скачивается запросом. Задержка — не меньше 10 минут. Хранение — 7 дней.
|
||||
Формат — CSV (RFC 4180) или JSON.
|
||||
|
||||
### Честно ли рассказывать про Kafka
|
||||
|
||||
Да, если называть вещи своими именами. Формулировка для курса:
|
||||
|
||||
> Kafka на стенде — учебная замена реальному транспорту. Основной путь выгрузки
|
||||
> у Яндекс Метрики — батч: Logs API отдаёт TSV-файл, и данных за сегодня в нём
|
||||
> нет. Поток у Метрики есть только в платном тарифе «Метрика Про» и идёт не
|
||||
> через Kafka, а через Yandex Data Transfer прямо в управляемый ClickHouse, с
|
||||
> задержкой до 15 минут. Kafka в этой схеме не участвует.
|
||||
|
||||
Почему Kafka всё-таки уместна на стенде:
|
||||
|
||||
- Задачи, которые она ставит перед менти, реальные: чтение из потока,
|
||||
контроль смещений, дубли, опоздавшие события, обратное давление. Такие задачи
|
||||
есть в любом продуктовом дата-контуре — просто перед Kafka там стоит свой
|
||||
коллектор, а не Метрика.
|
||||
- Механика «поток + версии одной записи» у Метрики Про (`Sign`, `HitVersion`,
|
||||
`VisitVersion`) ближе к потоковому приёму, чем к «скачал файл раз в сутки».
|
||||
Разговор про `ReplacingMergeTree` и `CollapsingMergeTree`, который стенд уже
|
||||
ведёт, попадает в реальную практику точно.
|
||||
|
||||
Чего делать нельзя: говорить менти «Яндекс отдаёт кликстрим в Kafka». Это
|
||||
неправда.
|
||||
|
||||
## 3. AppMetrica
|
||||
|
||||
Источник: [ресурсы Logs
|
||||
API](https://appmetrica.yandex.ru/docs/ru/mobile-api/logs/endpoints).
|
||||
|
||||
Главное отличие от Метрики: **AppMetrica отдаёт много узких таблиц вместо двух
|
||||
широких.** Каждый вид данных — свой эндпоинт: `events`, `installations`,
|
||||
`sessions_starts`, `ecommerce_events`, `revenue_events`, `ad_revenue_events`,
|
||||
`crashes`, `errors`, `clicks`, `postbacks`, `deeplinks`, `push_tokens`,
|
||||
`profiles_v2`. Формат — CSV или JSON.
|
||||
|
||||
Поле-строка с JSON **есть**: `event_json` — «атрибуты, сериализованные в JSON».
|
||||
То есть у мобильного трекера Яндекса произвольные свойства события лежат
|
||||
единым JSON в одной колонке — не так, как в Метрике с её массивами.
|
||||
|
||||
Метки времени у события — четыре, и это ровно то разделение, которого не
|
||||
хватает Метрике:
|
||||
|
||||
| Поле | Что это |
|
||||
|---|---|
|
||||
| `event_datetime` | Время события, `yyyy-mm-dd hh:mm:ss` |
|
||||
| `event_timestamp` | То же в unix-времени |
|
||||
| `event_receive_datetime` | Время приёма на сервере (расходится с `event_datetime` из-за сети) |
|
||||
| `event_receive_timestamp` | То же в unix-времени |
|
||||
|
||||
Идентификаторы: `appmetrica_device_id`, `installation_id`, `session_id`,
|
||||
`profile_id`. Устройство и гео: `device_manufacturer`, `device_model`,
|
||||
`device_type`, `os_name`, `os_version`, `city`, `country_iso_code`,
|
||||
`google_aid`, `ios_ifa`, `ios_ifv`.
|
||||
|
||||
Потоковые возможности — Data Stream API (см. выше): пятиминутные окна,
|
||||
задержка от 10 минут, хранение 7 дней, до 50 000 запросов в сутки против
|
||||
5 000 в сутки у Logs API.
|
||||
|
||||
## 4. Ecommerce и выручка
|
||||
|
||||
### Как это описывается на сайте
|
||||
|
||||
Источник: [передача данных
|
||||
ecommerce](https://yandex.ru/support/metrica/ru/ecommerce/data). Магазин кладёт
|
||||
в `dataLayer` объект такой формы:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"ecommerce": {
|
||||
"currencyCode": "RUB",
|
||||
"purchase": {
|
||||
"actionField": { "id": "TRX987", "revenue": 12300, "coupon": "SALE10" },
|
||||
"products": [
|
||||
{ "id": "SKU-1", "name": "Кружка", "price": 4100,
|
||||
"brand": "Acme", "category": "Посуда/Кружки",
|
||||
"variant": "белая", "quantity": 3 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Виды действий: `impressions`, `click`, `detail`, `add`, `remove`, `purchase`,
|
||||
`promoView`, `promoClick`. У покупки `actionField.id` обязателен; `revenue`
|
||||
считается автоматически, если его не передать. У товара обязателен `id` или
|
||||
`name`; остальное — `price`, `quantity`, `brand`, `category`, `variant`,
|
||||
`coupon`, `list`, `position`, `discount`.
|
||||
|
||||
### Что из этого попадает в выгрузку
|
||||
|
||||
**Не JSON, а плоские массивы.** Один заказ на 3 товара превращается не в
|
||||
вложенный объект, а в набор массивов одинаковой длины:
|
||||
|
||||
| Поле выгрузки | Тип | Что это |
|
||||
|---|---|---|
|
||||
| `ym:pv:purchaseID` | Array(String) | Идентификатор покупки |
|
||||
| `ym:pv:purchaseRevenue` | Array(Float64) | **Сумма заказа** |
|
||||
| `ym:pv:purchaseCurrency` | Array(String) | Валюта |
|
||||
| `ym:pv:purchaseCoupon` | Array(String) | Промокод на весь заказ |
|
||||
| `ym:pv:purchaseTax`, `purchaseShipping` | Array(String) | Налоги, доставка |
|
||||
| `ym:pv:purchaseProductQuantity` | Array(UInt64) | Число товаров в покупке |
|
||||
| `ym:pv:productID`, `productName`, `productBrand`, `productCategory` | Array(String) | Товар |
|
||||
| `ym:pv:productPrice` | Array(Int64) | Цена товара |
|
||||
| `ym:pv:productQuantity` | Array(UInt64) | Количество |
|
||||
| `ym:pv:productEventType` | Array(String) | `view_item_list`, `click`, `detail`, `add`, `purchase`, `remove` |
|
||||
| `ym:pv:ecommerce` | String | Сырое событие ecommerce (одна строка) |
|
||||
|
||||
Обратите внимание на две вещи. Первая: `purchaseTax` и `purchaseShipping` в
|
||||
хитах имеют тип `Array(String)`, хотя это денежные суммы, — так в документации.
|
||||
Вторая: рядом с разобранными массивами лежит поле `ym:pv:ecommerce` типа
|
||||
`String`. То есть Яндекс отдаёт и разобранное, и сырое.
|
||||
|
||||
На уровне визита к этому добавляются `ym:s:purchaseDateTime`
|
||||
`Array(DateTime)`, `ym:s:purchaseAffiliation`, весь блок
|
||||
`ym:s:purchasedProduct*` (около 20 массивов про купленные товары) и
|
||||
`ym:s:impressions*` (около 18 массивов про показы).
|
||||
|
||||
## 5. Как это кладут в ClickHouse
|
||||
|
||||
Здесь два первоисточника, и оба полезны.
|
||||
|
||||
### 5.1. Примерный датасет в документации ClickHouse
|
||||
|
||||
У ClickHouse корни в Метрике, и в его документации до сих пор лежит
|
||||
обезличенный датасет Метрики: `hits_v1` (8 873 898 строк) и `visits_v1`
|
||||
(1 680 609 строк). Источники:
|
||||
[страница датасета](https://clickhouse.com/docs/getting-started/example-datasets/metrica),
|
||||
DDL получен через MCP Context7 (`/clickhouse/clickhouse-docs`, файл
|
||||
`docs/getting-started/example-datasets/anon_web_analytics_metrica.md`).
|
||||
|
||||
`hits_v1` — примерно 130 плоских колонок:
|
||||
|
||||
```sql
|
||||
CREATE TABLE datasets.hits_v1
|
||||
(
|
||||
WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16,
|
||||
EventTime DateTime, EventDate Date, CounterID UInt32,
|
||||
ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32,
|
||||
UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8,
|
||||
URL String, Referer String, URLDomain String, RefererDomain String,
|
||||
IsRobot UInt8, RefererCategories Array(UInt16), URLRegions Array(UInt32),
|
||||
ResolutionWidth UInt16, ResolutionHeight UInt16,
|
||||
ClientTimeZone Int16, ClientEventTime DateTime, UTCEventTime DateTime,
|
||||
Params String, GoalsReached Array(UInt32),
|
||||
UTMSource String, UTMMedium String, UTMCampaign String,
|
||||
UTMContent String, UTMTerm String, FromTag String,
|
||||
HasGCLID UInt8, RefererHash UInt64, URLHash UInt64,
|
||||
CLID UInt32, YCLID UInt64,
|
||||
ParsedParams Nested(Key1 String, Key2 String, Key3 String,
|
||||
Key4 String, Key5 String, ValueDouble Float64),
|
||||
...
|
||||
)
|
||||
ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMM(EventDate)
|
||||
ORDER BY (CounterID, EventDate, intHash32(UserID))
|
||||
SAMPLE BY intHash32(UserID)
|
||||
```
|
||||
|
||||
Что тут стоит заметить:
|
||||
|
||||
- **Три метки времени:** `EventTime`, `ClientEventTime`, `UTCEventTime`. Плюс
|
||||
`ClientTimeZone`. Во внутренней схеме разделение клиента и сервера есть, хотя
|
||||
в публичную выгрузку хитов оно не попадает.
|
||||
- **Ключ сортировки** — `(CounterID, EventDate, intHash32(UserID))`: сначала
|
||||
сайт, потом дата, потом пользователь. Не идентификатор события. Это ключ под
|
||||
типовые запросы «по сайту за период», а не под точечный поиск.
|
||||
- **Ключ семплирования** `intHash32(UserID)` — чтобы считать по 10% данных и
|
||||
получать корректные метрики по пользователям.
|
||||
- **Nested** вместо параллельных массивов: `ParsedParams Nested(Key1 String,
|
||||
…, ValueDouble Float64)`. В ClickHouse `Nested` — это синтаксический сахар
|
||||
над теми же параллельными массивами: колонка `ParsedParams.Key1` физически и
|
||||
есть `Array(String)`.
|
||||
- Есть `YCLID UInt64` и `CLID UInt32` — метки Яндекс Директа.
|
||||
- Есть хеши (`URLHash`, `RefererHash`, `NormalizedRefererHash`) — внутренняя
|
||||
оптимизация Яндекса под быстрые сравнения.
|
||||
|
||||
`visits_v1` — около 190 колонок и другой движок:
|
||||
|
||||
```sql
|
||||
CREATE TABLE datasets.visits_v1
|
||||
(
|
||||
CounterID UInt32, StartDate Date, Sign Int8, IsNew UInt8,
|
||||
VisitID UInt64, UserID UInt64, StartTime DateTime, Duration UInt32,
|
||||
UTCStartTime DateTime, PageViews Int32, Hits Int32, IsBounce UInt8,
|
||||
...
|
||||
Goals Nested(ID UInt32, Serial UInt32, EventTime DateTime,
|
||||
Price Int64, OrderID String, CurrencyID UInt32),
|
||||
WatchIDs Array(UInt64),
|
||||
TraficSource Nested(ID Int8, SearchEngineID UInt16, AdvEngineID UInt8,
|
||||
PlaceID UInt16, SocialSourceNetworkID UInt8,
|
||||
Domain String, SearchPhrase String,
|
||||
SocialSourcePage String),
|
||||
ParsedParams Nested(Key1 String, ..., ValueDouble Float64),
|
||||
Market Nested(Type UInt8, GoalID UInt32, OrderID String,
|
||||
OrderPrice Int64, PP UInt32, ...,
|
||||
GoodID String, GoodName String,
|
||||
GoodQuantity Int32, GoodPrice Int64),
|
||||
...
|
||||
)
|
||||
ENGINE = CollapsingMergeTree(Sign)
|
||||
PARTITION BY toYYYYMM(StartDate)
|
||||
ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID)
|
||||
SAMPLE BY intHash32(UserID)
|
||||
```
|
||||
|
||||
Здесь `CollapsingMergeTree(Sign)` — тот самый механизм версий визита, о котором
|
||||
пишет справка Метрики Про. Ecommerce лежит в `Nested`-блоке `Market` с полями
|
||||
`GoodID`, `GoodName`, `GoodQuantity`, `GoodPrice`.
|
||||
|
||||
### 5.2. Официальные схемы потоковой выгрузки
|
||||
|
||||
Списки колонок для выгрузки в свой ClickHouse: [поля
|
||||
хитов](https://yandex.ru/support/metrica/ru/pro/hits), [поля
|
||||
визитов](https://yandex.ru/support/metrica/ru/pro/visits).
|
||||
|
||||
Существенное: **в облачной выгрузке имена колонок не в стиле API, а в стиле
|
||||
ClickHouse.** Не `ym:s:visitID`, а `VisitID`. Не `ym:pv:watchID`, а `WatchID`.
|
||||
Префиксы `ym:pv:` и `ym:s:` — это про язык API, в таблице их нет.
|
||||
|
||||
Колонки хитов, которые видит инженер:
|
||||
|
||||
| Колонка | Тип |
|
||||
|---|---|
|
||||
| `WatchID` | UInt64 |
|
||||
| `pageViewID` | UInt32 |
|
||||
| `VisitID` | UInt64 (с 10.10.2025) |
|
||||
| `CounterID` | UInt32 |
|
||||
| `ClientID` | UInt64 |
|
||||
| `CounterUserIDHash` | UInt64 |
|
||||
| `EventDate` | Date |
|
||||
| `UTCEventTime` | DateTime |
|
||||
| `ClientTimeZone` | Int16 |
|
||||
| `Sign` | Int8 — признак статуса записи в инкрементальном логе |
|
||||
| `HitVersion` | UInt32 |
|
||||
| `URL`, `Title` | String |
|
||||
| `GoalsReached` | Array(UInt32) |
|
||||
| `ecommerce` | String |
|
||||
|
||||
Колонок в хитовой выгрузке около 140, в визитной — около 200. В визитной есть
|
||||
`Sign` (Int8) и `VisitVersion` (UInt32).
|
||||
|
||||
Прицельная проверка по хитовой выгрузке: колонок `EventTime`,
|
||||
`ClientEventTime`, `LocalEventTime`, `UserID` и `UserIDHash` там **нет**.
|
||||
Единственная метка времени — `UTCEventTime`, а часовой пояс клиента — отдельным
|
||||
числом `ClientTimeZone`.
|
||||
|
||||
## 6. Сравнение с западными трекерами
|
||||
|
||||
**Snowplow — плоское ядро.** Обогащённое событие — строка TSV из 131 колонки.
|
||||
Таблица `atomic.events` описана как «широкая», и «отдельные поля хранятся в
|
||||
своих колонках». Самоописываемые события и сущности в BigQuery, Snowflake и
|
||||
Databricks добавляются как дополнительные колонки той же таблицы; в Redshift —
|
||||
отдельными таблицами со связью один-к-одному по `event_id`. Источник:
|
||||
[введение в таблицу atomic
|
||||
events](https://docs.snowplow.io/docs/fundamentals/warehouse-tables/).
|
||||
|
||||
**Segment — вложенный JSON.** Событие `track` — это JSON, где `properties` и
|
||||
`context` — вложенные объекты. Верхний уровень: `anonymousId`, `userId`,
|
||||
`event`, `properties`, `context`, `type`, `messageId`, `timestamp`,
|
||||
`originalTimestamp`, `sentAt`, `receivedAt`, `integrations`. Источник:
|
||||
[Spec: Track](https://www.twilio.com/docs/segment/connections/spec/track).
|
||||
|
||||
**Amplitude — вложенный JSON.** В Export API `event_properties`,
|
||||
`user_properties`, `group_properties`, `groups`, `data` — словари. Метки
|
||||
времени: `client_event_time`, `client_upload_time`, `event_time`,
|
||||
`server_upload_time`, `server_received_time`, `processed_time`. Источник:
|
||||
[Export API](https://amplitude.com/docs/apis/analytics/export).
|
||||
|
||||
**Итог сравнения.** Яндекс ближе к Snowplow: плоское широкое ядро, всё
|
||||
переменное — в массивах. Разница в том, что Snowplow добавляет колонки под
|
||||
каждую схему события, а Яндекс держит фиксированный набор массивов
|
||||
(`parsedParamsKey1..10`, `product*`, `purchase*`) и отдельное сырое поле
|
||||
(`params`, `ecommerce`). До Segment и Amplitude, где `properties` — свободный
|
||||
JSON-объект, Яндексу далеко.
|
||||
|
||||
## Вывод: что копировать стенду
|
||||
|
||||
### Форма
|
||||
|
||||
**Плоское широкое событие с массивами.** Одно событие = одна строка. Внутри —
|
||||
плоские колонки. Всё, что бывает «много раз внутри одного события», — набор
|
||||
параллельных массивов одной длины (или `Nested`, что в ClickHouse то же самое).
|
||||
Свободного вложенного JSON вроде `context` или `properties` не делать: в РФ
|
||||
менти его не встретит.
|
||||
|
||||
Стенду стоит воспроизводить именно **хит** — одно действие с полным контекстом.
|
||||
Визит оставить тем, чем он сейчас является: результатом сборки в DDS/DM. Так
|
||||
менти сам делает то, что Метрика делает за него, и понимает, откуда берётся
|
||||
`visitDuration` и `pageViews`.
|
||||
|
||||
Отдельно рекомендуется добавить **одно сырое поле-строку с JSON** — как
|
||||
`ym:pv:ecommerce` у Метрики и `event_json` у AppMetrica. Это даёт честное
|
||||
упражнение «разобрать JSON внутри колонки», которое в бою встречается постоянно.
|
||||
|
||||
### Список полей для широкого события стенда
|
||||
|
||||
Колонка «есть» — про текущий стенд (`sql/ddl/ods/20_ods.sql`,
|
||||
`sql/ddl/dds/30_dds.sql`). «нет» означает: поля у нас сейчас нет.
|
||||
|
||||
| № | Имя | Тип | Откуда взято | Есть у нас |
|
||||
|---|---|---|---|---|
|
||||
| 1 | `WatchID` | UInt64 | `ym:pv:watchID`, `hits_v1.WatchID` | ~ (есть `event_id` UUID, тип другой) |
|
||||
| 2 | `VisitID` | UInt64 | `ym:pv:visitID`, `visits_v1.VisitID` | ~ (есть `click_id` UUID, тип другой) |
|
||||
| 3 | `pageViewID` | UInt32 | `ym:pv:pageViewID` | **нет** |
|
||||
| 4 | `CounterID` | UInt32 | `ym:pv:counterID` | **нет** |
|
||||
| 5 | `ClientID` | UInt64 | `ym:pv:clientID` — анонимный id браузера | **нет** ← важное |
|
||||
| 6 | `CounterUserIDHash` | UInt64 | `ym:pv:counterUserIDHash` | **нет** |
|
||||
| 7 | `UTCEventTime` | DateTime | `Метрика Про, хиты` | ~ (есть `event_ts`, одна метка) |
|
||||
| 8 | `EventDate` | Date | `Метрика Про, хиты` | есть (`event_date`) |
|
||||
| 9 | `ClientTimeZone` | Int16 (минуты) | `ym:pv:clientTimeZone` | **нет** ← важное |
|
||||
| 10 | `ClientEventTime` | DateTime | `hits_v1.ClientEventTime`; у AppMetrica — `event_datetime` против `event_receive_datetime` | **нет** ← важное |
|
||||
| 11 | `URL` | String | `ym:pv:URL` | есть (`page_url`) |
|
||||
| 12 | `Title` | String | `ym:pv:title` | **нет** |
|
||||
| 13 | `Referer` | String | `ym:pv:referer` | есть (`referer_url`) |
|
||||
| 14 | `UTMSource` | String | `ym:pv:UTMSource` | есть |
|
||||
| 15 | `UTMMedium` | String | `ym:pv:UTMMedium` | есть |
|
||||
| 16 | `UTMCampaign` | String | `ym:pv:UTMCampaign` | есть |
|
||||
| 17 | `UTMContent` | String | `ym:pv:UTMContent` | есть |
|
||||
| 18 | `UTMTerm` | String | `ym:pv:UTMTerm` | **нет** |
|
||||
| 19 | `LastTrafficSource` | String | `ym:pv:lastTrafficSource` | ~ (есть `referer_medium`, смысл близкий) |
|
||||
| 20 | `LastSearchEngineRoot` | String | `ym:pv:lastSearchEngineRoot` | **нет** |
|
||||
| 21 | `HasGCLID` | UInt8 | `ym:pv:hasGCLID` | **нет** |
|
||||
| 22 | `YCLID` | UInt64 | `hits_v1.YCLID` (в Logs API не найден) | **нет** |
|
||||
| 23 | `Browser` | String | `ym:pv:browser` | есть (`browser_name`) |
|
||||
| 24 | `BrowserMajorVersion` | UInt16 | `ym:pv:browserMajorVersion` | **нет** |
|
||||
| 25 | `BrowserLanguage` | String | `ym:pv:browserLanguage` | есть (`browser_language`) |
|
||||
| 26 | `OperatingSystem` | String | `ym:pv:operatingSystem` | есть (`os`) |
|
||||
| 27 | `OperatingSystemRoot` | String | `ym:pv:operatingSystemRoot` | есть (`os_name`) |
|
||||
| 28 | `DeviceCategory` | String (1..4) | `ym:pv:deviceCategory` | есть (`device_type`) |
|
||||
| 29 | `MobilePhoneModel` | String | `ym:pv:mobilePhoneModel` | **нет** |
|
||||
| 30 | `ScreenWidth`, `ScreenHeight` | UInt16 | `ym:pv:screenWidth/Height` | **нет** |
|
||||
| 31 | `IPAddress` | String | `ym:pv:ipAddress` | есть (`ip_address`) |
|
||||
| 32 | `RegionCountry` | String (ISO) | `ym:pv:regionCountry` | есть (`geo_country`) |
|
||||
| 33 | `RegionCity` | String | `ym:pv:regionCity` | ~ (есть `geo_region_name`) |
|
||||
| 34 | `RegionCountryID`, `RegionCityID` | UInt32 | `ym:pv:regionCountryID/CityID` | **нет** ← важное |
|
||||
| 35 | `IsPageView` | UInt8 | `ym:pv:isPageView` | **нет** |
|
||||
| 36 | `NotBounce` | UInt8 | `ym:pv:notBounce` | **нет** |
|
||||
| 37 | `HTTPError` | String | `ym:pv:httpError` | **нет** |
|
||||
| 38 | `GoalsReached` | Array(UInt32) | `ym:pv:goalsID`, `hits_v1.GoalsReached` | **нет** ← ключевое |
|
||||
| 39 | `ParsedParams` | Nested(Key1..Key5 String, ValueDouble Float64) | `hits_v1.ParsedParams`; в Logs API — `parsedParamsKey1..10` | **нет** ← ключевое |
|
||||
| 40 | `Params` | String (сырой JSON) | `ym:pv:params` | **нет** |
|
||||
| 41 | `ecommerce` | String (сырой JSON) | `ym:pv:ecommerce`; у AppMetrica — `event_json` | **нет** ← ключевое |
|
||||
| 42 | `purchaseID` | Array(String) | `ym:pv:purchaseID` | **нет** ← ключевое |
|
||||
| 43 | `purchaseRevenue` | Array(Float64) | `ym:pv:purchaseRevenue` — **выручка** | **нет** ← ключевое |
|
||||
| 44 | `purchaseCurrency` | Array(String) | `ym:pv:purchaseCurrency` | **нет** |
|
||||
| 45 | `purchaseCoupon` | Array(String) | `ym:pv:purchaseCoupon` | **нет** |
|
||||
| 46 | `productID` | Array(String) | `ym:pv:productID` | **нет** ← ключевое |
|
||||
| 47 | `productName` | Array(String) | `ym:pv:productName` | **нет** |
|
||||
| 48 | `productCategory` | Array(String) | `ym:pv:productCategory` | **нет** |
|
||||
| 49 | `productPrice` | Array(Int64) | `ym:pv:productPrice` | **нет** ← ключевое |
|
||||
| 50 | `productQuantity` | Array(UInt64) | `ym:pv:productQuantity` | **нет** ← ключевое |
|
||||
| 51 | `productEventType` | Array(String) | `ym:pv:productEventType`: `detail`, `add`, `remove`, `purchase`… | **нет** ← ключевое |
|
||||
| 52 | `Sign` | Int8 | Метрика Про, хиты и визиты | **нет** ← ключевое |
|
||||
| 53 | `HitVersion` | UInt32 | Метрика Про, хиты | **нет** |
|
||||
|
||||
Поля 38–53 — то, чего стенду не хватает сильнее всего: цели, свои параметры,
|
||||
ecommerce с выручкой и механика версий записи. Ровно про это спрашивают на
|
||||
работе в первую очередь, и ровно этого сейчас у нас нет
|
||||
(см. `docs/generator-realism.md`, раздел «Что упрощено»).
|
||||
|
||||
Ключ сортировки для широкой таблицы стенда стоит взять по образцу Метрики:
|
||||
`ORDER BY (CounterID, EventDate, intHash32(ClientID))`, а не по идентификатору
|
||||
события. Это заодно повод объяснить менти, зачем ключ сортировки строится под
|
||||
запросы, а не под уникальность.
|
||||
|
||||
### Чего воспроизводить не стоит
|
||||
|
||||
1. **Полный набор полей.** 140 колонок в хитах и 200 в визитах — это шум.
|
||||
Учебной ценности в 56 массивах нет никакой, а поддерживать их дорого.
|
||||
Хватит 40–50 колонок из таблицы выше.
|
||||
2. **Отдельную сущность «визит» из Яндекса.** Если брать и хиты, и визиты,
|
||||
стенд потеряет главное упражнение — сборку сессий своими руками. Берём
|
||||
только хиты.
|
||||
3. **Полную механику `CollapsingMergeTree` с пересчётом визита.** Колонку
|
||||
`Sign` добавить полезно — это узнаваемо и объясняет `sum(Sign)`. А вот
|
||||
пересчитывать визит и присылать по нему пять версий — сложность, которая
|
||||
съест урок целиком. Достаточно показать `Sign` на хитах.
|
||||
4. **Устаревшие технологии из датасета ClickHouse.** `FlashMajor`,
|
||||
`SilverlightVersion1..4`, `NetMajor` — следы 2013 года. Живой аналог
|
||||
сегодня им не соответствует, копировать нечего.
|
||||
5. **Хеши** (`URLHash`, `RefererHash`, `NormalizedStartURLHash`). Это
|
||||
внутренняя оптимизация Яндекса. Менти без контекста примет их за содержимое.
|
||||
6. **Социально-демографические поля** (`Age`, `Sex`, `Income`, `Interests`,
|
||||
`GeneralInterests`, `Robotness`). Это внутренние оценки Яндекса, вне Яндекса
|
||||
их не получить. Ставить их в генератор — учить менти работать с данными,
|
||||
которых у него не будет.
|
||||
7. **Openstat и поля Яндекс Директа** (`openstatAd`, `openstatCampaign`,
|
||||
`DirectClickOrder`, `DirectBannerGroup`, `DirectPhraseOrCond` и десяток
|
||||
соседних). Openstat — устаревший стандарт метки трафика. Поля Директа
|
||||
осмысленны только при связке аккаунтов. Ставим одну метку `YCLID` и одну
|
||||
`HasGCLID` — этого хватит для разговора об атрибуции.
|
||||
8. **Пять уровней категорий товара** (`productCategoryLevel1..5`) и блоки
|
||||
`purchasedProduct*` (~20 массивов), `impressions*` (~18 массивов),
|
||||
`promotion*`, `offlineCall*`. Механика та же, что у `product*`; повторять её
|
||||
четыре раза — только объём.
|
||||
9. **Префиксы `ym:pv:` и `ym:s:` в именах колонок.** Это язык API, а не имена
|
||||
в базе. Сам Яндекс в облачной выгрузке их не использует.
|
||||
10. **Смену UUID на UInt64 у наших `event_id` и `click_id`.** У Яндекса
|
||||
идентификаторы числовые, но переделывать под это весь стенд — работа без
|
||||
учебной отдачи. Достаточно добавить `ClientID` типа UInt64 — это самое
|
||||
узнаваемое поле Метрики, и его отсутствие у нас заметнее всего.
|
||||
11. **`browser_user_agent` как «поле Метрики».** У Яндекса строки user agent в
|
||||
выгрузке нет — отдаются уже разобранные поля. Само поле на стенде оставить
|
||||
можно (разбор user agent — реальная задача), но нельзя выдавать его за
|
||||
формат Яндекса.
|
||||
12. **`geo_latitude` и `geo_longitude` как «поля Метрики».** Координат в
|
||||
выгрузке Метрики нет. Если они нужны для карт в Superset, надо честно
|
||||
сказать, что это наша добавка.
|
||||
|
||||
## Что осталось неподтверждённым
|
||||
|
||||
- Поле `UserID` (свой идентификатор пользователя со стороны сайта) в списках
|
||||
выгружаемых полей Logs API и в облачной выгрузке хитов найти не удалось.
|
||||
- Поле `yclid` в Logs API не найдено. Колонка `YCLID UInt64` есть в примерном
|
||||
датасете ClickHouse.
|
||||
- Ограничение «не более 1 ГБ на один файл выгрузки» встречается в поиске по
|
||||
документации Метрики, но дословно на официальной странице не подтверждено.
|
||||
- Сколько времени хранится подготовленный лог до удаления — на изученных
|
||||
страницах не сказано; сказано только, что удалять их надо самому, иначе
|
||||
кончится квота 10 ГБ.
|
||||
- Экспорт кликстрима Метрики в Yandex Object Storage или в Yandex Data Streams
|
||||
(сервис с Kafka-совместимым интерфейсом) официальной документацией не
|
||||
подтверждён. Единственный подтверждённый потоковый приёмник — управляемый
|
||||
ClickHouse через Yandex Data Transfer.
|
||||
- Точное число колонок в облачной выгрузке (около 140 для хитов, около 200 для
|
||||
визитов) — оценка по объёму страниц, а не цифра из документации.
|
||||
|
||||
## Источники
|
||||
|
||||
Яндекс Метрика, Logs API:
|
||||
|
||||
- [Введение в Logs API](https://yandex.ru/dev/metrika/ru/logs/)
|
||||
- [Поля хитов](https://yandex.ru/dev/metrika/ru/logs/fields/hits)
|
||||
- [Поля визитов](https://yandex.ru/dev/metrika/ru/logs/fields/visits)
|
||||
- [Блог Метрики: выгружайте сырые данные через Logs API](https://yandex.ru/blog/metrika/vygruzhayte-syrye-dannye-iz-metriki-cherez-logs-api)
|
||||
- [setUserID](https://yandex.com/support/metrica/en/objects/set-user-id.html)
|
||||
|
||||
Яндекс Метрика, выгрузка в облако:
|
||||
|
||||
- [Data Streaming (интеграция с Yandex Cloud)](https://yandex.ru/support/metrica/ru/uploading-data/cloud)
|
||||
- [Метрика Про: как работать с данными](https://yandex.ru/support/metrica/ru/pro/data-work)
|
||||
- [Метрика Про: поля хитов](https://yandex.ru/support/metrica/ru/pro/hits)
|
||||
- [Метрика Про: поля визитов](https://yandex.ru/support/metrica/ru/pro/visits)
|
||||
- [Yandex Cloud: репликация данных Метрики в ClickHouse](https://yandex.cloud/ru/docs/tutorials/dataplatform/metrika-to-clickhouse)
|
||||
|
||||
Ecommerce:
|
||||
|
||||
- [Передача данных ecommerce](https://yandex.ru/support/metrica/ru/ecommerce/data)
|
||||
|
||||
AppMetrica:
|
||||
|
||||
- [Logs API: ресурсы и поля](https://appmetrica.yandex.ru/docs/ru/mobile-api/logs/endpoints)
|
||||
- [Data Stream API: описание](https://appmetrica.yandex.ru/docs/ru/mobile-api/datastream/about)
|
||||
|
||||
ClickHouse:
|
||||
|
||||
- [Примерный датасет Метрики](https://clickhouse.com/docs/getting-started/example-datasets/metrica)
|
||||
- DDL таблиц `hits_v1` и `visits_v1` получен через MCP Context7
|
||||
(`/clickhouse/clickhouse-docs`, файл
|
||||
`docs/getting-started/example-datasets/anon_web_analytics_metrica.md`)
|
||||
|
||||
Западные трекеры:
|
||||
|
||||
- [Snowplow: введение в таблицу atomic events](https://docs.snowplow.io/docs/fundamentals/warehouse-tables/)
|
||||
- [Segment Spec: Track](https://www.twilio.com/docs/segment/connections/spec/track)
|
||||
- [Amplitude Export API](https://amplitude.com/docs/apis/analytics/export)
|
||||
Reference in New Issue
Block a user