Зачем: убрать механические повторы в итогах и избежать ложных расхождений при проверке графика Superset. Что: уточнены правила итоговых списков и название задания о проверках заказов. В разборе событий разделены учет повторных доставок и выбор событий ODS для сравнения. Первый график Superset и проверочный SQL используют весь период витрины. Проверка: git diff --check, локальные ссылки и переходы к измененным заголовкам прошли. Блоки кода и таблицы требований сохранены. Согласованность периода графика с SQL проверена по тексту; повторный проход через интерфейс Superset не выполнялся.
111 lines
7.4 KiB
Markdown
111 lines
7.4 KiB
Markdown
# Задание 2: `dm.top_pages_daily`
|
||
|
||
**Чему учит:** собрать дневные показатели страниц и настроить их
|
||
обновление в `dm_transform` через замену партиций.
|
||
|
||
## Сначала прочитать
|
||
|
||
- [«Хранилище и его слои»](../handbook/storage-layers.md);
|
||
- [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md).
|
||
|
||
## Для чего нужна витрина
|
||
|
||
По дневным показателям страниц аналитик сравнивает просмотры, посетителей и
|
||
действия с товарами. Добавление в корзину происходит на карточке товара,
|
||
покупка — на странице подтверждения заказа. Отношение добавлений к
|
||
просмотрам карточки показывает ее конверсию.
|
||
|
||
Для воронки «просмотр → корзина → покупка» этих данных недостаточно:
|
||
действия происходят на разных страницах, а связи между ними в агрегате нет.
|
||
Путь человека исследуют по событиям или сессиям.
|
||
|
||
## Что сделать
|
||
|
||
Источник — `dds.event_v`. Зерно витрины — **день события × страница**.
|
||
Читайте DDS напрямую: так выполнение задания не зависит от витрины
|
||
задания 1.
|
||
|
||
На стенде витрину с новым зерном хранят как готовый агрегат, чтобы не
|
||
рассчитывать ее заново для каждого запроса. Причины описаны в разделе
|
||
[«Как принято на ступени 1»](README.md#как-принято-на-ступени-1). Создайте
|
||
пять объектов:
|
||
`dm.top_pages_daily_rep` / `_dist`, донор `_stage_rep` / `_stage_dist` и
|
||
публичное представление `dm.top_pages_daily_v`. Ключ партиции — день, он же
|
||
единица пересборки.
|
||
|
||
### Состав колонок
|
||
|
||
| Колонка | Тип | Значение |
|
||
|---|---|---|
|
||
| `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`, заполните донор за весь диапазон одной вставкой,
|
||
затем замените дневные партиции по одной.
|
||
|
||
### Ключ шардирования
|
||
|
||
Выберите ключ самостоятельно. У `revenue_daily` кроме дня одно измерение с
|
||
шестью близкими по объему значениями. Здесь страниц много, и число событий
|
||
на них сильно различается.
|
||
|
||
У цели и донора используйте одинаковый ключ: иначе при замене партиции
|
||
строка потеряется на одном шарде и удвоится на другом. О том, [как устроен
|
||
донор](../architecture/storage.md), читайте в разделе «Раскладка по шардам».
|
||
|
||
## Типичная ошибка
|
||
|
||
Из-за имени витрины хочется отобрать только просмотры. Но фильтр источника
|
||
по `event_type = 'pageview'` обнулит `cart_adds` и `purchases`, а запрос не
|
||
завершится ошибкой. Конверсия карточек станет нулевой. Проверка одной суммы
|
||
`pageviews` не обнаружит этот фильтр: все просмотры остались на месте.
|
||
Ошибку покажет сверка `purchases` или `cart_adds` с источником, если за день
|
||
были покупки или добавления в корзину.
|
||
|
||
Выбирайте проверку под возможную ошибку. Этот подход описан в
|
||
[справочнике проверок](../architecture/testing.md).
|
||
|
||
## Как проверить себя
|
||
|
||
Деловой ключ — `page_path` внутри дня. Получите прямой агрегат из
|
||
`dds.event_v` за день и соедините его с `dm.top_pages_daily_v` полным
|
||
внешним соединением по ключу. Посчитайте строки, где ключ отсутствует с
|
||
одной из сторон или различается любой из четырех счетчиков. Расхождений
|
||
должно быть ноль.
|
||
|
||
Перед полным сравнением проверьте дневные суммы:
|
||
|
||
- сумма `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` и убедились, что повторный
|
||
прогон конвейера не меняет результат.
|