# Задание 2: показатели страниц по дням, `dm.top_pages_daily` В этой работе вы рассчитаете показатели страниц за каждый день и сохраните их в таблице. Затем подключите обновление витрины к `dm_transform`: новый расчет будет заменять дневные партиции таблицы. ## Подготовка - [«Хранилище и его слои»](../handbook/storage-layers.md); - [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md). ## Дневные показатели страниц По дневным показателям страниц аналитик сравнивает просмотры, посетителей и действия с товарами. Добавление в корзину происходит на карточке товара, покупка — на странице подтверждения заказа. Отношение добавлений к просмотрам карточки показывает ее конверсию. Для воронки «просмотр → корзина → покупка» этих данных недостаточно: действия происходят на разных страницах, а связи между ними в агрегате нет. Путь человека исследуют по событиям или сессиям. ## Создание витрины Читайте события из `dds.event_v`. В результате нужна одна строка на страницу за день. Например, все просмотры одной карточки товара за один день попадут в одну строку. Витрина задания 1 для этого расчета не нужна. Сохраните рассчитанные показатели в таблице, чтобы отчеты читали готовые итоги. Создайте пять объектов: - основные таблицы `dm.top_pages_daily_rep` и `dm.top_pages_daily_dist`; - промежуточные таблицы `dm.top_pages_daily_stage_rep` и `dm.top_pages_daily_stage_dist`; - представление для чтения `dm.top_pages_daily_v`. Их назначение и порядок обновления разобраны во вводной: [«Создание и обновление витрин»](README.md#создание-и-обновление-витрин). Разбейте данные на партиции по дням, чтобы можно было заменить результат одного дня целиком. ### Состав колонок | Колонка | Тип | Значение | |---|---|---| | `report_date` | `Date` | День события | | `page_path` | `LowCardinality(String)` | Путь страницы | | `pageviews` | `UInt64` | Число событий `pageview` на странице | | `visitors` | `UInt64` | Число разных `client_id` на странице | | `cart_adds` | `UInt64` | Число событий `add_to_cart` на странице | | `purchases` | `UInt64` | Число событий `purchase` на странице | | `_load_id` | `String` | Идентификатор запуска, собравшего день | | `_load_ts` | `DateTime64(3, 'UTC')` | Время сборки | Вычислите `page_path` из `url`, убрав домен и параметры запроса. Полный адрес разделил бы показатели одной страницы на сотни строк. Учитывайте все три типа событий, а их счетчики вычисляйте через `countIf`. ### Дни для пересчета События завершившегося модельного дня больше не меняются. Найдите первый такой день, которого еще нет в витрине, и рассчитайте все дни от него до последнего завершившегося. Если начать после последнего дня, который уже есть в витрине, можно пропустить более ранний день, не загруженный из-за сбоя. Как у `revenue_daily`, запишите расчет за все выбранные дни в промежуточную таблицу одной вставкой. Затем замените дневные партиции основной таблицы по одной. Добавьте запуск этих запросов в `dm_transform`. ### Ключ шардирования Выберите ключ самостоятельно. У `revenue_daily` строки сгруппированы по дню и категории товара; категорий всего шесть. Здесь страниц много, и число событий на них сильно различается. У основной и промежуточной таблиц используйте одинаковый ключ шардирования. Замена партиции не перераспределяет строки между шардами. Подробнее об этом в разделе [«Раскладка по шардам»](../architecture/storage.md#раскладка-по-шардам). ## Типичная ошибка Из-за имени витрины хочется отобрать только просмотры. Но фильтр источника по `event_type = 'pageview'` обнулит `cart_adds` и `purchases`, а запрос не завершится ошибкой. Конверсия карточек станет нулевой. Проверка одной суммы `pageviews` не обнаружит этот фильтр: все просмотры остались на месте. Ошибку покажет сверка `purchases` или `cart_adds` с источником, если за день были покупки или добавления в корзину. Выбирайте проверку под возможную ошибку. Этот подход описан в [справочнике проверок](../architecture/testing.md). ## Проверка результата Рассчитайте те же показатели по `dds.event_v` за выбранный день. Сопоставьте результат со строками `dm.top_pages_daily_v` за этот день через `FULL OUTER JOIN` по `page_path`. Найдите страницы, которые есть только с одной стороны, и строки, где различается хотя бы один из четырех счетчиков. Расхождений должно быть ноль. Перед полным сравнением проверьте дневные суммы: - сумма `pageviews` равна числу событий `pageview` в `dds.event_v`; - сумма `purchases` равна числу событий `purchase` в том же источнике. Сумма `visitors` по страницам повторно учитывает посетителя, открывшего несколько страниц. Число посетителей за день берите из `dm.daily_traffic_v`. ## Результат работы - [ ] у вас есть пять объектов витрины; промежуточная таблица объявлена через `AS` и использует тот же ключ шардирования, что и основная; - [ ] в `dm.top_pages_daily_v` явно перечислены колонки, включая `_load_id` и `_load_ts`; - [ ] ваш запрос сам определяет дни пересборки по состоянию витрины; - [ ] проверка `top_pages_daily` в `homework_check` прошла успешно; - [ ] вы включили витрину в `dm_transform` и убедились, что повторный прогон конвейера не меняет результат.