Зачем: план состава отдаёт дневную аудиторию, но событий у мира ещё не было. День-функция превращает аудиторию в поток просмотров — на нём стоят лабы про сборку визитов и про витрины, а следующий этап вешает на него торговые события. Что: - `day.py` — день как чистая функция зерна и номера дня: суточная волна в местном времени посетителя, визиты по документированным правилам нарезки, все 47 колонок выгрузки; шов для торговых событий — ряды `page` и `product`; - `reference.py` — справочники-литералы: профили устройств, города Поволжья с настоящими гео-id Яндекса, источники трафика, карта сайта; - `catalog.py` и `data/catalog/products.csv` — каталог на 180 позиций, общий у генератора и будущего словаря ClickHouse; - `weights.py` — выбор по целым весам, один на план и на день; - паспорт куки (устройство и город) переехал в план состава; броски приписаны последними, поэтому измеренные числа канонического мира не сдвинулись; - словарь: «визит» закреплён за сессией, одноимённое понятие плана стало «днём активности»; статьи в `CONTEXT.md`; - решения по ходу — в спеку генератора, раздел 9; наполнение `ParsedParamsKey1` отложено тикетом #47. Проверка: `make lint`, `make typecheck`, `make test` — 353 passed (было 297). Счётчики плана после правки те же: приток 3827,64/день, дневная аудитория 6235–7124, 68 119 посетителей за 14 дней, 170 двухкуковых пар. День 0 — 45 810 событий за 0,6 с, снимок 14 дней — 5,9 с при пороге 30 с на день. Две слепые линии ревью, десять находок, все закрыты и перепроверены. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9.8 KiB
Описание выгрузки: событие кликстрима
Документ собран из контракта схемы генератора
(generator/src/clickstream_generator/schema.py). Руками не править —
пересобрать: make docs.
Одно событие — одна строка: хит по образцу облачной выгрузки Яндекс Метрики.
Многозначное лежит в параллельных массивах одной длины, плюс одно сырое
JSON-поле ecommerce. Отдельной сущности «визит» в выгрузке нет — визиты
собирают на стороне хранилища, а VisitID дан как эталон для самопроверки.
Имена и типы колонок — стороны источника. Хранилище принимает их как есть и нормализует у себя: то же имя в нашем стиле ждёт в столбце «Нормализованное имя». Это имя источника, приведённое к snake_case, а не имя атрибута в модели данных: слой DDS складывает свою модель и называет атрибуты по ней. Столбец «Тип numpy» показывает, чем колонка представлена внутри генератора; у массивов это тип элемента. Номер — место колонки в выгрузке: порядок задан контрактом.
Колонки группы «Ecommerce» заполнены только у торговых событий:
add_to_cart несёт один товар, purchase — состав заказа и блок
purchase*. У остальных событий они пусты.
Всего колонок: 47.
Идентификаторы и время
| № | Колонка | Тип ClickHouse | Тип numpy | Нормализованное имя | Комментарий |
|---|---|---|---|---|---|
| 1 | WatchID |
UInt64 |
uint64 |
watch_id |
id события — хита; держится ниже 2^53, выше числа в JSON округляются |
| 2 | VisitID |
UInt64 |
uint64 |
visit_id |
id визита от генератора — эталон лабы: собери сессии сам и сравни |
| 3 | ClientID |
UInt64 |
uint64 |
client_id |
анонимный id браузера — кука; по хешу от неё таблица шардируется |
| 4 | CounterID |
UInt32 |
uint32 |
counter_id |
id счётчика: на стенде константа, сайт один |
| 5 | EventDate |
Date |
datetime64[D] |
event_date |
дата события в часовом поясе счётчика; по ней режется партиция. Дату из UTCEventTime не выводить: у ночных событий она на сутки другая |
| 6 | UTCEventTime |
DateTime |
datetime64[s] |
utc_event_time |
время события в UTC — единственная метка времени, как у Метрики; сутки же считаются в поясе счётчика, поэтому toDate(UTCEventTime) ≠ EventDate |
| 7 | ClientTimeZone |
Int16 |
int16 |
client_timezone |
смещение часового пояса клиента от UTC, в минутах |
| 8 | EventType |
LowCardinality(String) |
object |
event_type |
тип события: pageview, add_to_cart, purchase — добавка стенда, у Метрики такого поля нет |
| 9 | Sign |
Int8 |
int8 |
sign |
всегда 1: колонка формата, исправлений записей генератор не шлёт |
Страница и атрибуция
| № | Колонка | Тип ClickHouse | Тип numpy | Нормализованное имя | Комментарий |
|---|---|---|---|---|---|
| 10 | URL |
String |
object |
url |
адрес страницы события |
| 11 | Referer |
String |
object |
referer |
адрес, с которого посетитель пришёл на страницу |
| 12 | Title |
String |
object |
title |
заголовок страницы |
| 13 | UTMSource |
String |
object |
utm_source |
метка utm_source: площадка перехода |
| 14 | UTMMedium |
String |
object |
utm_medium |
метка utm_medium: тип трафика |
| 15 | UTMCampaign |
String |
object |
utm_campaign |
метка utm_campaign: рекламная кампания |
| 16 | UTMContent |
String |
object |
utm_content |
метка utm_content: что различает объявления одной кампании |
| 17 | UTMTerm |
String |
object |
utm_term |
метка utm_term: ключевое слово перехода |
| 18 | LastTrafficSource |
String |
object |
last_traffic_source |
последний источник трафика: organic, direct, ad и подобные |
| 19 | HasGCLID |
UInt8 |
uint8 |
has_gclid |
1, если в адресе была метка Google Ads |
| 20 | YCLID |
UInt64 |
uint64 |
yclid |
id клика Яндекс Директа; без метки — 0 |
Браузер, устройство, гео
| № | Колонка | Тип ClickHouse | Тип numpy | Нормализованное имя | Комментарий |
|---|---|---|---|---|---|
| 21 | Browser |
String |
object |
browser |
браузер посетителя |
| 22 | BrowserMajorVersion |
UInt16 |
uint16 |
browser_major_version |
старшая версия браузера |
| 23 | BrowserLanguage |
String |
object |
browser_language |
язык браузера |
| 24 | OperatingSystem |
String |
object |
operating_system |
операционная система с версией |
| 25 | OperatingSystemRoot |
String |
object |
operating_system_root |
семейство операционной системы, без версии |
| 26 | DeviceCategory |
UInt8 |
uint8 |
device_category |
тип устройства кодами Метрики: 1 — десктоп, 2 — телефон, 3 — планшет, 4 — телевизор; у Метрики это строка, у нас число |
| 27 | MobilePhoneModel |
String |
object |
mobile_phone_model |
модель телефона; на десктопе пусто |
| 28 | ScreenWidth |
UInt16 |
uint16 |
screen_width |
ширина экрана в пикселях |
| 29 | ScreenHeight |
UInt16 |
uint16 |
screen_height |
высота экрана в пикселях |
| 30 | IPAddress |
String |
object |
ip_address |
IP-адрес посетителя |
| 31 | RegionCountry |
String |
object |
region_country |
страна кодом ISO |
| 32 | RegionCity |
String |
object |
region_city |
город, название по-английски |
| 33 | RegionCountryID |
UInt32 |
uint32 |
region_country_id |
числовой id страны в справочнике регионов Яндекса |
| 34 | RegionCityID |
UInt32 |
uint32 |
region_city_id |
числовой id города в том же справочнике |
Массивы и параметры
| № | Колонка | Тип ClickHouse | Тип numpy | Нормализованное имя | Комментарий |
|---|---|---|---|---|---|
| 35 | GoalsReached |
Array(UInt32) |
uint32 |
goals_reached |
id достигнутых целей; на стенде их две — корзина и покупка |
| 36 | ParsedParamsKey1 |
Array(String) |
object |
parsed_params_key1 |
свои параметры сайта, один уровень — например вариант A/B-теста |
Ecommerce
| № | Колонка | Тип ClickHouse | Тип numpy | Нормализованное имя | Комментарий |
|---|---|---|---|---|---|
| 37 | purchaseID |
Array(String) |
object |
purchase_id |
номер заказа; у события purchase — один элемент |
| 38 | purchaseRevenue |
Array(Float64) |
float64 |
purchase_revenue |
выручка заказа глазами клиента; Float64, как у Метрики — на этом держится урок о расхождениях с бэкендом |
| 39 | purchaseCurrency |
Array(String) |
object |
purchase_currency |
валюта заказа |
| 40 | purchaseCoupon |
Array(String) |
object |
purchase_coupon |
купон заказа, если был применён |
| 41 | productID |
Array(String) |
object |
product_id |
id товаров события |
| 42 | productName |
Array(String) |
object |
product_name |
названия тех же товаров |
| 43 | productCategory |
Array(String) |
object |
product_category |
категории тех же товаров |
| 44 | productPrice |
Array(Int64) |
int64 |
product_price |
цена за штуку целым числом: деньги генератор считает целыми |
| 45 | productQuantity |
Array(UInt64) |
uint64 |
product_quantity |
количество штук каждого товара |
| 46 | productEventType |
Array(String) |
object |
product_event_type |
действие с товаром: стенд шлёт add и purchase, полный словарь Метрики (detail, remove, impressions) не берём |
| 47 | ecommerce |
String |
object |
ecommerce |
сырой JSON события, как отдаёт Метрика — материал лабы про разбор JSON внутри колонки |