Создание метрик
Одним из преимуществ Trisigma является наличие продвинутой системы расчета метрик и их разрезов. Эта система обеспечивает порядок и единообразие расчетов и интерпретации метрик на уровне всей компании, предотвращая ситуации, где два человека внутри одной компании могут посчитать одну и ту же метрику по-разному. Порядок определяется стандартизированной процедурой заведения метрик в систему. Об этой системе мы поговорим подробнее ниже.
Шаг 1. Получить доступ к репозиторию метрик#
О том, как его создать и как с ним работать, читайте здесь.
В репозитории, к которому вы получили доступ, лежат три папки: sources
, metrics
и dimensions
. Рассмотрим подробнее их содержимое.
Папка sources
#
Папка sources
— это папка, в которой необходимо определить источники, из которых в дальнейшем мы будем считать метрики. Внутри этой папки:
- Папка
sql
: содержит все SQL-запросы для формирования источников расчета метрик. - YAML файл: здесь описаны параметры источника данных, который определен в папке
sql
.
📌 Важно отметить, что в процессе интеграции команда Trisigma помогает с настройкой интеграции с DWH, поэтому от клиента требуется только правильно указать название источника и таблицы.
Папка metrics
#
Папка metrics
— это папка, в которой необходимо описать YAML файл для расчета метрик. Каждый YAML файл в этой папке содержит набор метрик, которые считаются на одном источнике.
Метрики внутри каждого YAML файла бывают трех типов. Каждый тип записывается в отдельном блоке файла:
metric.counter
Простые каунтеры.#
Каунтеры — это тип метрик, которые получаются путем фильтрации нужных строк и сложения по выбранному полю. Можно перечислить несколько полей (столбцов), тогда все они будут сложены друг с другом.
Аргументы:
filter
: условие, фильтрующее нужные строки перед тем, как их сложить. Синтаксис описан в Таблице 1 ниже.obs
: колонка (или список), значения которой нужно складывать. Если не указана, то подставляется1
(по сути, будет считаться количество строк).
Таблица 1. Синтаксис формирования метрики-каунтера
(где a
— имя поля, к которому применяется какая-то операция)
Оператор | Примеры | Аналог в SQL (Trino) |
---|---|---|
<=, >=, <, >, =, != |
a.>=: 1 , a.!= 1 |
a >= 1 , a <> 1 |
like, !like |
a.like: 'доставка' , a.!like: 'доставка' |
a like 'доставка' , a not like 'доставка' |
ilike, !ilike |
a.ilike: 'доставка' , a.!ilike: 'доставка' |
a ilike 'доставка' , a not ilike 'доставка' |
bit, !bit |
a.bit: 3 , a.!bit: 3 |
bitwise_and(a, 3) > 0 , bitwise_and(a, 3) = 0 |
in, !in |
a.in: [1, 2, 3] , a.!in: [4, 5, 6] |
a in (1, 2, 3) , a not in (4, 5, 6) |
Условие в фильтре имеет формат ключ-значение. Ключом является имя столбца в источнике. В поле obs
указываются столбцы, которые нужно сложить. Например, метрику с конфигом phone_views: {filter: [eid: 303], obs: [events_count]}
в SQL можно вычислить как select sum(events_count) as phone_views from source where eid = 303
.
Особенности синтаксиса:
- К столбцам в фильтре можно применять операторы. Оператор применяется через точку, например
filter_name.>: 30
. Выбранный для фильтрации оператор, таким образом, всегда окружен точкой слева и двоеточием справа, после которого идет значение, по которому фильтруем. - Можно также сделать условие со сравнением колонок по типу
col1.>: $col2
, где доллар позволяет ссылаться на другое поле в пределах одногоsource
. - В случае необходимости сложения нескольких полей (столбов) синтаксис выглядит как
obs: [А, Б, С]
, что соответствует логике(сумма по полю А) + (сумма по полю Б) + (сумма по полю С)
.
❗️YAML файлы имеют преимущества, которые можно использовать при заведении метрик. Так, в YAML можно определять выражения вверху файла и использовать ссылки на эти выражения через символ &
.
Пример:
Заведение метрики example_premium_user_payments
Без использования возможностей YAML:
metric.counter:
example_premium_user_payments: {
filter: [is_premium_user: true, event_id.in: [55, 57, 67]],
obs: []
}
С использованием возможностей YAML:
definitions:
- &is_premium_user
{is_premium_user: true}
- &payment_evnts
{event_id.in: [55, 57, 67]}
metric.counter:
example_premium_user_payments:
filter: [*is_premium_user, *payment_evnts]
obs: []
Есть также ключевые слова $and
, $or
, которые позволяют писать более сложные конструкции. Например, если мы хотим фильтровать ИЛИ премиум пользователей, ИЛИ тех, кто совершили оплату, синтаксис будет следующий:
definitions:
- &is_premium_user
{is_premium_user: true}
- &payment_evnts
{event_id.in: [55, 57, 67]}
metric.counter:
example_premium_user_payments:
filter:
[$or: [*is_premium_user, *payment_evnts]]
obs: []
metric.uniq
Уникальные.#
Уникальные — это тип метрик, которые считают уникальные ключи (уникальных пользователей, события и т.д.).
Аргументы:
counter
: имя каунтера из первого блока (metric.counter
). Обязательное поле.key
: колонка, уникальные значения которой мы считаем. Может быть составным ключом, и все перечисленные в этом поле колонки будут использованы для сбора хэша. По сути является сокращённым способом записи дляkey_seq
, состоящего из одного уровня группировки. Обязательное поле.key_seq
: иерархия колонок, по которым по порядку будут проверятьсяthreshold
и выполняться группировки (см. пример ниже).thresholds
: пороги, по которым учитываем уникальные значения при условииsum(counter) > threshold
. Если не указан, то0
.
Пример:
Пример использования key_seq
:
Допустим, что мы хотим завести метрику, которая будет считать количество премиум-пользователей, совершивших более 10 оплат (example_prem_user_10plus_payments
). Она будет считаться так же, как метрика количество премиум-пользователей, совершивших оплату (example_premium_user_payments
), но с применением порога по числу оплат (>10).
example_prem_user_10plus_payments:
{
counter: example_premium_user_payments,
key_seq: [user_id, event_id],
thresholds: [10, 0]
}
В данном случае будет выполняться следующий запрос:
SELECT SUM(CASE WHEN payments > 0 THEN 1 END) AS num -- посчитали юзеров, тут не нужен трешхолд
FROM (
SELECT user_id,
SUM(CASE WHEN payments > 10 THEN 1 END) AS payments -- посчитали число оплат на каждого юзера, проверили трешхолд в 10 оплат
FROM (
SELECT user_id,
event_id,
COUNT(*) AS payments -- сгруппировали по юзеру и типу оплаты, посчитали, сколько было оплат каждого типа (event_id), трешхолд не проверяем
FROM example_table
GROUP BY user_id, event_id
) AS temp1
GROUP BY user_id
) AS temp2
❗️ metric.uniq
имеют особенности расчета: ключ считается как уникальный только в рамках одного дня. Например, если user_id
— это ключ, и мы хотим посчитать метрику "число заходов в приложение" по этому ключу, то если пользователь зашел 5 раз в течение одного дня, число заходов в приложение по ключу user_id
посчитается как 1
. Если пользователь заходил по одному разу в день в течение 5 дней, то число заходов в приложение посчитается как 5
.
metric.ratio
Метрики отношения.#
Это метрики, представляющие собой отношение каких-то других величин. Например, можно рассчитать соотношение: CR в добавление в корзину/CR в добавление в заказ. Оба аргумента — ссылки на существующие метрики (имена метрик) из пп. 1-2.
Аргументы:
num
: числитель. Обязательное поле.den
: знаменатель. Обязательное поле.
❗️Числитель и знаменатель ratio
-метрики могут быть прописаны в любом файле, даже если у них разные источники. Это возможно, потому что ratio
метрики состоят из метрик, расчет которых вы уже объявили заранее, и программа знает, как посчитать числитель и знаменатель, независимо от того, в каком YAML файле они находятся.
💡 Мы рекомендуем прописывать ratio
-метрику в том конфиге, где содержится числитель.
Папка dimensions
#
dimensions
(разрезы) — это папка, предназначение которой напоминает справочник. В ней необходимо определить разрезы, которые могут быть у метрики (например, регион, категория товара, сегмент пользователей) и описать, как эти разрезы читать в отчете. Внутри этой папки:
-
Папка
sql
: здесь находятся SQL-скрипты, "справочники", которые содержат поля-маппинги для описанияdimensions
.В этих скриптах описывается, какие значения соответствуют ключам (
value_id
), а какие — значениям (value
). Например,region_id
— этоvalue_id
, аregion
— этоvalue
.Описав таким образом регион, мы передаем алгоритму информацию о том, как нужно читать
id
регионов для дальнейшего использования, например, в отчетах по А/В тестам (если там будет использован данный разрез). -
YAML файл: здесь описаны параметры каждого
dimension
, который определен в папкеdimensions/sql
.
Новые dimensions
заводятся для того, чтобы иметь возможность добавлять их в слайсы (брейкдауны) в отчетах по АБ тестам в Trisigma.
📌 Важно отметить, что заводить dimensions
нужно относительно редко. Один и тот же dimension
можно использовать для тысяч метрик. Главное — проверить, что у источника в source.yaml
, на котором вы строите метрику, есть нужное поле для создания dimension
.
Шаг 2. Определяем источники данных#
Для определения источника нам необходимо:
- Написать SQL-запрос, который сформирует таблицу со всеми необходимыми для расчета метрик и разрезов полями.
- Сохранить этот SQL-запрос в файл с расширением
.sql
. - Поместить файл с расширением
.sql
в папкуsources/sql
. - Описать параметры источника в файле
sources.yaml
. - Сохранить изменения.
❗️SQL-запрос должен содержать параметры :first_date
и :last_date
(эти параметры определяют период, за который будет рассчитана метрика. Подробнее здесь).
Как описывать поля в YAML файле?
Необходимо указать следующие параметры:
sql
— имя файла с SQL-кодом источника. Обязательное поле.dimensions
— список дименшенов (ключи изdimensions.yaml
), которые есть в источнике.participant
— маппинг, какой столбец отвечает заvisitor
, а какой заuser
(обычноcookie_id
иuser_id
). Обязательное поле, если метрика будет использоваться в А/В тестах (отвечает за единицу рандомизации в эксперименте).primary_subject
— по какомуparticipant
распараллеливать вычисления метрики. Обычно этоuser
, если он есть. Обязательное поле (в будущих релизах поле будет упразднено).dtm
— колонка с датой/таймстампом. Обязательное поле.
💡 При первичной настройке источников мы рекомендуем ответить на вопрос: "Из какой таблицы в нашей инфраструктуре данных мы сможем посчитать наибольшее количество полезных метрик?" Если у вас есть такая таблица, заведите её в папку sources
самой первой простым запросом через select * from ваша_таблица
(не забывая про :first_date
и :last_date
). Это позволит вам быстро и эффективно начать обогащать Trisigma метриками, не тратя время на создание большого количества источников.
❗️ Один источник может иметь только один primary_subject
, то есть данные для расчета разных метрик на одном источнике всегда будут считаться по одному primary_subject
. Если один и тот же источник необходимо посчитать с разными primary_subject
, нужно завести отдельные источники под разные primary_subject
.
Шаг 3. Создаем метрику#
Для создания метрики необходимо:
- Создать YAML файл в котором будут находиться метрики, привязанные к одному источнику данных (см. рисунок 1).
- Связать YAML файл с источником данных Для этого в конфиге источника (в
sources.yaml
) укажите имя созданного YAML файла с метрикой в полеmetric_configs
. - Определить тип метрики которую вы хотите создать (
metric.counter
,metric.uniq
илиmetric.ratio
). - Определить поля и фильтры по которым метрика будет считаться.
- Написать YAML конфиг для данной метрики, используя описанный выше синтаксис.
- Сохранить изменения
📌 Важно отметить, что на один источник можно создавать несколько YAML файлов с метриками. В таком случае в YAML конфиге источника необходимо добавлять имена зависящих от него YAML файлов с метриками через запятую в поле metric_configs
, например: metric_configs: [metric_config1, metric_config2, metric_config3]
.
💡 Мы рекомендуем заранее договориться внутри вашей компании о системе нейминга метрик, если сейчас такой системы нет. С ростом количества метрик ориентироваться в них будет все сложнее. Прозрачная система нейминга поможет упростить поиск метрик и навигацию по ним.
Шаг 4. Создаем Dimension#
Для создания dimensions (разрезов) метрики необходимо:
- Написать SQL-запрос, который сформирует таблицу с маппингами
<dimension_name>_id → dimension_name
. - Переименовать
<dimension_name>_id
вvalue_id
иdimension_name
вvalue
. Это важно, так как Trisigma распознает толькоvalue_id
иvalue
как допустимые имена полей для dimension. - Сохранить этот SQL-запрос в файл с расширением
.sql
. - Поместить файл с расширением
.sql
в папкуdimensions/sql
. - Описать файл с SQL-запросом** в файле
dimensions.yaml
.
❗️Если поле для создания dimension не имеет вид <dimension_name>_id
, то SQL-запрос может выгружать единственное поле, которое будет содержать все значения dimension_name.
❗️Не забывайте переименовывать поля в value
и value_id
.
Пример:
SELECT segment_id AS value_id, -- <dimension_name>_id
segment AS value -- dimension_name
FROM dict.segments_df
Как описывать поля в YAML файле?
has_id
— в источниках dimension представлен в виде id, столбец имеет имя<dimension_name>_id
.is_bool
— уточнение того, является ли dimension булевым. В таком случае dimension не требуется YAML-справочник.parent
— слаг parent dimension, если есть.description
— краткое описание dimension.slug
— сокращенное имя dimension, то, как имя dimension будет отображаться в отчете по результатам А/В теста (например,logical_category
→slug: logcat
).
Шаг 5. Создаем PR и мерджим ветку с новой метрикой#
- Создаем PR.
- Делаем доработки
- Пушим изменения
- Билд валидации запустится автоматически
- Результат работы билда отобразится в комментариях PR
- В случае успеха введите команду
run merge
Это последний шаг по заведению метрик. После успешного создания метрики и мерджа, на странице метрики в Trisigma можно увидеть сгенерированный SQL и проверить логику расчета.
Cheat Sheet: связь между конфигами#
В процессе заведения метрик необходимо не забывать возвращаться к source
файлу и устанавливать с ним связи из конфигов метрик или разрезов. Чтобы не запутаться, пользуйтесь схемой ниже.
Мастер-класс по заведению метрик#
В этом разделе мы решим практическую задачу по заведению метрики example_premium_user_payments_u
: количество уникальных премиум-пользователей, совершивших оплату.
-
Заводим источник
Напишем SQL запрос и положим его в папку
sources/sql
.Файл с этим запросом назовем
example_source.sql
:SELECT event_date, cookie_id, user_id, event_id, is_premium_user, device_type FROM dwh.clickstream_events WHERE event_date :: date BETWEEN :first_date AND :last_date
Опишем источник в YAML конфиге
sources.yaml
:example_source: # называем также, как SQL, чтобы не запутаться metric_configs: - example_config_clickstream_evnts sql: example_source dimensions: - device_type participant: user: user_id visitor: cookie_id primary_subject: user dtm: event_date
📌 Все поля из source не обязательно описывать в конфиге. Какая-то часть полей может быть использована для расчета метрик или разрезов, но не быть описанной в конфиге источника.
-
Заводим метрику
example_premium_user_payments_u
Создадим файл
example_config_clickstream_evnts.yaml
в папкеmetrics
, где будут описаны все метрики, рассчитанные по источникуexample_source
:В этом конфиге сначала создается метрикаmetric.counter: example_premium_user_payments: filter: - is_premium_user: true - event_id.in: - 55 - 57 - 67 obs: [] metric.uniq: example_premium_user_payments_u: counter: example_premium_user_payments key: - user # не user_id, а user
counter
, которая отбирает только премиум клиентов, которые совершили оплату (event_id = 55, 57 или 67 это ID совершения оплаты). Параметрobs
не заполняется в данном кейсе, поэтому для метрики посчитается число строк в отфильтрованной таблице. Далее со ссылкой наcounter
создаетсяuniq
метрика, где уникализация (count distinct) будет происходить поuser
.❗️ Проверяем, что в конфиге источника, по которому будет рассчитываться наша метрика
example_premium_user_payments_u
, в полеmetric_configs
вписано название конфига метрик, которые будут рассчитываться на этом источнике. -
Заводим dimensions Допустим, мы хотим, чтобы для нашей метрики можно было смотреть отчет с разрезами по
device_type
. Напишем SQL запрос и положим его в папкуdimensions/sql
. Файл с этим запросом назовемdevice_type.sql
:Внесем описание этого dimension в YAML конфиг со всеми существующими dimensions:SELECT device_type AS value FROM dict.device_types
device_type: description: "Тип устройства, с которого была произведена оплата"
has_id
не заполняем, поскольку в источниках dimension имеет имяdevice_type
, а не представлен в виде<dimension_name>_id
.❗️ Проверяем, что в конфиге источника, по которому будет рассчитываться наша метрика
example_premium_user_payments_u
, в полеdimensions
вписан dimension -device_type
. -
Создаем PR и мерджим ветку с новой метрикой по инструкции выше.
-
Смотрим сгенерированный SQL и проверяем логику расчета на странице метрики в Trisigma. Готово!
Ответы на популярные вопросы#
-
Как часто будут обновляться данные по метрикам?
Данные отчета обновляются раз в 24 часа.
-
Зачем нужны параметры
:first_date
и:last_date
?Эти параметры нужны для того, чтобы более эффективно отфильтровать данные при выполнении SQL-запросов. Конфиг источников метрик уже содержит информацию о том, какая колонка отвечает за дату, и фильтр по дате применяется следующим образом:
Однако compute движок (например, Trino) не всегда эффективно применяет этот фильтр, что может привести к чтению избыточного количества данных из хранилища. Использование параметровSELECT ... FROM ( {{ source_sql }} ) WHERE date_col BETWEEN :first_date AND :last_date
first_date
иlast_date
прямо внутри SQL источника позволяет разместить фильтры в любом месте запроса. Это особенно актуально для сложных SQL запросов, включающих вложенные запросы, группировки и т.д. -
Что делать, если при заведении источника/метрики/разреза произошла ошибка?
Попробуйте исправить ошибку самостоятельно: внимательно прочитайте текст ошибки в комментарии к PR и исправьте ее. Если не удается решить проблему, обратитесь в чат, где обсуждали интеграцию, или напишите на почту contact@trisigma.io.