Попробовать

Особенности создания DAX-параметров

В данной статье мы рассмотрим процесс создания кастомных параметров на DAX-подобном языке. Ознакомиться с подробным описанием работы в интерфейсе, синтаксисом, алгоритмом создания показателей можно по ссылке: https://smartanalytics.io/ru/blog/documentation/osobennosti-primenenija-dax/. После того, как базовые вопросы по функционалу DAX закрыты, можно переходить к особенностям создания параметров.

Отличия DAX-параметров от метрик

Первой отличительной чертой является выбор из списка категории dim, а не metric:

Вторым отличием является перечень функций, доступных к использованию. На данный момент реализованы следующие функции: CONCATENATE, TOSTRING, LEN, LOWER, UPPER, REPLACE, TRIM, REPT, SUBSTRING, EXTRACT, SPLITBYCHAR, ARRAYELEMENT, ABS, ACOS, ACOSH, ASIN, ASINH, ATAN, ATANH, CEILING, COS, COSH, DIVIDE, EVEN, EXP, INT, LOG, LOG10, PI, ROUND, SIGN, SIN, SINH, SQRT, TAN, TANH. Все функции можно поделить на группы.

Математические функции

Функции для работы с текстом

Логические функции

Примеры использования функций

Стоит отметить, что ряд функций поддерживает гибкий подход к формированию ожидаемого результата. А их комбинация и вовсе дает широкий простор для кастомизации параметра. Рассмотрим примеры применения наиболее сложных функций для работы с текстом.

Кейс 1. Гибкое извлечение фрагмента данных из строки по регулярному выражению.

Для решения данной задачи нам потребуется воспользоваться функцией EXTRACT, которая имеет следующий шаблон:

EXTRACT([поле], '(?:искомый_параметр_1|искомый_параметр_2)=(.*?)разделитель')

Данное выражение разделено на две условные части. В первой записывается поле, по значениям которого производится поиск фрагмента. А во второй, используя язык регулярных выражений, записывается условие выделения части текста и записи его в новый параметр.

Принцип работы заключается в том, что мы задаем условие начального фрагмента, выполняющего роль ключа к поиску нужного значения и конечного, как некого флага для завершения поиска строки, а результатом работы является вывод промежуточного значения.

В синтаксис функции заложены такие правила, что искомый параметр объявляется символами ‘?:’, при этом, если требуется внести перечень искомых  значений (например, если мы ищем любое из них), то их перечисление осуществляется через вертикальный слеш ‘|’.

Дальше, при необходимости, указывается символ (например, знак равенства или слеш), если это является отличительной общей чертой перечисленных раньше параметров. Например, для поиска значений utm_term или utm_content в строке ‘https://smartanalytics.io/ru/solutions/skvoznaya-analitika-new-3b/?utm_campaign=12345&utm_term=skvoznaya-analitika&utm_medium=cpc’ запись примет следующий вид: «(?:utm_term|utm_content)=».

Далее в скобках указывается выражение с использованием символов регулярных выражений, где точка означает один любой символ, звездочка означает повторение предыдущего символа 0 и более раз, знак вопроса – один символ или ни одного. В данном выражении мы прописываем, какой результат хотим видеть от работы функции: один символ или несколько. После этого мы записываем разделитель, до которого вырезаем значение из строки по ключу. Разделитель может быть любым символом.

Важно! Чтобы компилятор не считал любой символ за команду, стоит его экранировать (например, слеш ‘/’, не являющийся математическим действием, примет следующую форму ‘\/’, то есть мы добавляем обратный слеш, как команду для экранирования нашего слеша).

Кейс 2. Извлечение данных с конкретной позиции.

Для решения данного кейса можно воспользоваться двумя функциями ARRAYELEMENT и SPLITBYCHAR.

Если данные лежат строками, то предварительно нужно разбить строку на элементы по разделителю, после чего определить позицию нужного элемента, начиная отсчет с 1. Формула для вырезания 4 элемента из строк типа ‘https://main/menu/tovary/dlya-detei’, содержащихся в поле [url], примет вид:

ARRAYELEMENT(SPLITBYCHAR('/', [url]), 4)

Тогда новый параметр будет содержать значение ‘menu’, поскольку при разделении строки на первой позиции будет ‘https:’, на второй – » (пустая строка между двумя разделителями), на третьей – ‘main’, на четвертой – ‘menu’, на пятой – ‘tovary’, на шестой – ‘dlya-detei’.

Помимо этого, если количество элементов в строке разнится, и нужно вывести, например, последний, тогда формула примет вид:

ARRAYELEMENT(SPLITBYCHAR('/', [url]), -1)

Здесь ‘-1’ – это указание на последний элемент, соответственно, логика такова, что если нужен предпоследний элемент, то необходимо прописать в формуле ‘-2’ и т.д.

Также важно отметить, что функции работают и по отдельности, шаблоны для них выглядят следующим образом:

ARRAYELEMENT([поле], номер_элемента)
SPLITBYCHAR('разделитель', [поле])

Кейс 3. Вариативная формула.

Если встречается такая ситуация, что прописать одной лишь функции недостаточно, поскольку в новом параметре появляются пустые строки, от которых нужно избавиться, то на помощь придет использование конструкции IF.

Общий шаблон примет вид:

IF(условие1 != '', условие1, 'none')

Логика работы алгоритма будет заключаться в том, что мы проверяем условие (под условием подразумевается любая функция, как в кейсах 1-2) на наличие только непустых значений, в противном случае записываем в них ‘none’ (может быть и другое значение).

Например, для кейса 1 формула с проверкой на ненулевые значения будет выглядеть следующим образом:

IF(EXTRACT([url], '(?:utm_term|utm_content)=(.*?)&') != '', EXTRACT([url], '(?:utm_term|utm_content)=(.*?)&'), 'none')

Для кейса 2 конструкция будет выглядеть аналогичным образом:

IF(ARRAYELEMENT(SPLITBYCHAR('/', [url]), 4) != '', ARRAYELEMENT(SPLITBYCHAR('/', [url]), 4), 'none')

Кейс 4. Мультивариативная формула.

Может быть и такое, что одной ветки условий недостаточно и требуется более гибкий подход. Тогда можно воспользоваться конструкцией MULTIIF, которая включает в себя возможность прописывать ряд условий по шаблону:

MULTIIF(условие1, выполнение1, условие2, выполнение2, условие3, выполнение3, иначе)

Здесь важно учитывать, что на каждой нечетной позиции, кроме последней, стоит условиеN, которое проверяется, и если оно выдает результат TRUE, то в параметр записывается результат выполненияN, в случае если все условия прошли проверку, но результат TRUE получен не был, в параметр запишется результат выражения «иначе», стоящего на последнем, обязательном месте.

Пример гибкой логики выражения с использованием MULTIIF:

MULTIIF(ARRAYELEMENT(SPLITBYCHAR('/', [enter_url]), 4) == 'support', ARRAYELEMENT(SPLITBYCHAR('/', [enter_url]), 5), AND(ARRAYELEMENT(SPLITBYCHAR('/', [enter_url]), 4) == 'delivery', ARRAYELEMENT(SPLITBYCHAR('/', [enter_url]), 6) != ''), ARRAYELEMENT(SPLITBYCHAR('/', [enter_url]), 6), 'search and others')

В данном примере две ветки условий, в первом случае результатом будет запись 5 элемента параметра, если 4 элемент равен значению ‘support’, во втором (условие с оператором AND является составным) – запись 6 элемента, если 4 элемент равен ‘delivery’ И 6 элемент не равен пустой строке, в остальных случаях будет записано выражение ‘search and others’.

Рассмотренная конструкция позволяет делать кастомные параметры с высокой степенью гибкости.

Кейс 5. Преобразование формата вывода текста в параметре.

В данном примере рассмотрим работу функций LOWER, UPPER, REPLACE. Предположим основная логика работы формулы уже описана, но необходимо добавить вывод значений исключительно в верхнем регистре, а дефисы заменить на пробелы, тогда формула примет вид:

REPLACE(UPPER(EXTRACT([url],'(?:utm_term=)(.*?)&')), '-', ' ')

Разберем формулу по частям. Первая, уже известная нам, часть направлена на вырезание ключевого слова из строки от значения ‘utm_term=’ до разделителя ‘&’:

EXTRACT([url],'(?:utm_term=)(.*?)&')

Вторая часть преобразует вывод вырезанного ранее фрагмента в верхний регистр:

UPPER(EXTRACT([url],'(?:utm_term=)(.*?)&'))

Соответственно, если нас интересует вывод в нижнем регистре, требуется воспользоваться функцией LOWER по тому же принципу:

LOWER(EXTRACT([url],'(?:utm_term=)(.*?)&'))

Третья заключительная часть логики работы формулы заменяет встречающиеся дефисы в строке на пробелы с помощью функции REPLACE:

REPLACE(UPPER(EXTRACT([url],'(?:utm_term=)(.*?)&')), '-', ' ')

Описанный пример хорошо показывает широкий простор кастомизации решений путем комбинирования различных функций.