Работа с RQL-запросами
В данном разделе описано, как использовать язык запросов R-Vision SIEM для анализа событий и записей активных списков. Описано создание запросов, которые включают работу с проекциями, использование условий, управление выводом, сортировку и группировку результатов, а также заполнение данных. Также описывается использование фильтров и временных ограничений в поиске.
В данной статье при описании выражений приняты следующие обозначения:
|
Содержание раздела:
Синтаксис запросов
RQL-запросы используются для поиска и извлечения информации о событиях безопасности и записях активных списков.
Работа с событиями в R-Vision осуществляется только в рамках определенного хранилища. Поэтому, в отличие от SQL, в запросах не требуется указывать таблицу базы данных в компоненте FROM <имя таблицы>
.
RQL-запросы используются в разделах Дашборды и Поиск. В разделе Поиск доступны два режима поиска — базовый и продвинутый, в последнем случае доступны использование проекций и группировка результатов.
[SELECT *] [{expression}] -- условие
[(INNER | LEFT) JOIN `active_list_name` [AS alias_name] ON {expression} [ENRICH target_field = source_field]]
[ORDER BY field_name [ASC | DESC] [WITH FILL [FROM {expression} TO {expression}] STEP {expression}]]
[LIMIT {m} [OFFSET {n}]]
SELECT {expression} [AS alias_name][, {expression}]
[(INNER | LEFT | RIGHT | FULL) JOIN `active_list_name` [AS alias_name] ON {expression} [ENRICH target_field = source_field]]
[WHERE {expression}]
[GROUP BY field_name [HAVING {expression}]]
[ORDER BY field_name [ASC | DESC] [WITH FILL [FROM {expression} TO {expression}] STEP {expression}]]
[LIMIT {m} [OFFSET {n}]]
Запрос в SQL | Запрос в системе |
---|---|
|
|
|
|
|
|
|
|
Фильтры в разделе Поиск и ограничения по времени применяются как дополнительные условия для запроса.
Работа с проекциями (оператор SELECT)
В R-Vision SIEM для каждого хранилища событий выбирается ref:EventModel.adoc[модель событий], а для активного списка — схема активного списка, которые определяют структуру данных. По умолчанию система возвращает результат со всеми полям текущей модели данных или схемы активного списка независимо от того, какие поля отображаются в списке. Поэтому, если в результат необходимо включить все поля, в базовом поиске компонент запроса SELECT *
может опускаться.
Оператор SELECT
используется при работе с проекциями, то есть для указания определенных полей, которые будут включены в результат запроса. Этот оператор часто используется в виджетах и метриках, которые создаются на дашбордах. Имена полей в запросе отделяются друг от друга запятыми.
SELECT {expression}[, {expression}]
Не ставьте разделитель после последнего поля, включенного в запрос. |
Оператор SELECT
является обязательным при использовании оператора WHERE
и группировке результатов.
Запрос в SQL | Запрос в системе |
---|---|
|
|
|
|
Использование псевдонимов (оператор AS)
При редактировании виджетов и метрик удобно использовать псевдонимы, которые позволяют сократить названия компонентов запроса в секции Сопоставление полей.
SELECT {expression} AS alias_name
Пример использования псевдонима для функции
При создании виджета типа Таблица вводится запрос:
SELECT collectorId, count(*) AS cnt WHERE collectorId LIKE '%' GROUP BY collectorId
Здесь для функции count(*)
задается псевдоним cnt
, который можно указать в секции сопоставления полей.
Использование условий (оператор WHERE)
В базовом поиске при задании условия оператор WHERE
в запросе опускается.
При использовании проекций оператор WHERE
позволяет применять к указанному полю запрос с выборкой строк по определенному условию.
SELECT {expression} WHERE {expression}
В условиях используются операторы сравнения, работы с множествами и проверки на пустое значение.
Пример выборки строк по условию
WHERE
SELECT tenantId WHERE length(tenantId) = 5
Этот запрос возвращает события с количеством символов в поле tenantId
, равным 5.
Операторы сравнения
Оператор | Значение |
---|---|
|
Равно |
|
Неравно |
|
Меньше |
|
Меньше или равно |
|
Больше |
|
Больше или равно |
|
Соответствует заданному шаблону |
|
Не соответствует заданному шаблону |
|
Входит в диапазон. |
|
Не входит в диапазон. |
Операторы работы с множествами (IN) и проверки на пустое значение
Оператор | Значение |
---|---|
|
Входит во множество |
|
Не входит во множество |
|
Значение является пустым (NULL) |
|
Значение не является пустым (NULL) |
Комбинирование условий (операторы AND, OR, NOT)
Совмещение нескольких условий происходит с использованием операторов:
Оператор | Значение |
---|---|
|
Конъюнкция (И) |
|
Дизъюнкция (ИЛИ) |
|
Логическое отрицание |
Пример запроса с комбинированным условием
Рассмотрим запрос, возвращающий события, у которых значения в поле tenantId
начинаются с символа n, а количество символов в поле raw
превышает 10.
SELECT * FROM table WHERE tenantId LIKE 'n%' AND length(raw) > 10
tenantId LIKE 'n%' AND length(raw) > 10
Работа с настраиваемыми полями универсальной модели
В RQL-запросах доступно обращение к регулярным настраиваемым полям универсальной модели события. Обращение к таким полям может осуществляться как напрямую, так и посредством специального синтаксиса.
{custom_field}:{custom_field_label} {expression}
Здесь:
-
{custom_field}
— ключ значения настраиваемого поля, например:cn1
,cs1
,deviceCustomDate1
,c6a1
.Вместо ключа конкретного поля можно использовать его семейство, зависящее от типа данных значения в этом поле:
-
cs
—LCString
; -
cn
—UInt64
; -
c6a
—IPv6
; -
deviceCustomDate
—DateTime
.Семейство полей рекомендуется использовать в случаях, когда требуется проверять условие {expression}
по всем полям этого семейства.
-
-
{custom_field_label}
— поле метаданных, хранящее метку, которая указывает на содержание и назначение связанного с ним поля{custom_field}
. Эта метка играет роль названия для поля{custom-field}
и позволяет интерпретировать хранящиеся в нем данные. -
{custom_field_label}
— поле метаданных, хранящее метку, которая указывает на содержание и назначение связанного с ним поля{custom_field}
. Эта метка играет роль названия для поля{custom_field}
и позволяет интерпретировать хранящиеся в нем данные.Примеры меток:
-
cn1Label
— для поляcn1
; -
cs1Label
— для поляcs1
; -
deviceCustomDate1Label
— для поляdeviceCustomDate1
; -
c6a1Label
— для поляc6a1
.
-
-
{expression}
— выражение с условием поиска по полю значения, использующее операции сравнения (=
,!=
,<>
,<
,>
,<=
,>=
) и/или операторыIN
,LIKE
,NOT LIKE
.
|
Примеры обращения к настраиваемым полям
Пример обращения к полю напрямую
Допустим, имеется поток событий, у которых в поле cs1
хранится адрес электронной почты пользователя, совершившего подозрительное действие. Известно, что часть событий является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется исключить из рассматриваемого потока тестовые события. Ниже представлен вариант соответствующего RQL-запроса с непосредственным обращением к полю cs1
.
cs1 != "test@example.com"
Запрос выдаст события, поле cs1
которых не содержит значение test@example.com
.
Пример обращения к полю по его ключу
Допустим, имеется поток событий от разных источников. Для событий от некоторых источников в поле cs1
хранится адрес электронной почты пользователя, совершившего подозрительное действие. В соответствующем поле метки cs1Label
этих событий хранится значение email
. Известно, что часть событий от этих источников является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется получить поток событий, для которых указаны электронные адреса пользователей, и исключить из него тестовые события. Ниже представлен RQL-запрос, построенный на основе представленного ранее синтаксиса. Обращение к полю cs1
выполняется по его ключу.
cs1:email != "test@example.com"
Запрос выдаст события, для которых одновременно выполняются следующие условия:
-
Поле
cs1
не содержит значениеtest@example.com
. -
Поле
cs1Label
содержит названиеemail
.
Представленный запрос эквивалентен следующему запросу:
cs1 != "test@example.com" AND cs1Label = "email"
Пример обращения к полю по его семейству
Допустим, имеется поток событий из разных источников. Для событий некоторых источников в полях семейства cs
(например, cs1
, cs2
, cs3
) хранится адрес электронной почты пользователя, совершившего подозрительное действие. В соответствующих полях меток (например, cs1Label
, cs2Label
, cs3Label
) этих событий хранится значение email
. Известно, что часть событий от этих источников является тестовой и приходит от разных пользователей с одним и тем же электронным адресом test@example.com
.
Требуется получить поток событий, для которых указаны электронные адреса пользователей, и исключить из него тестовые события. Ниже представлен RQL-запрос, построенный на основе представленного ранее синтаксиса. Обращение к настраиваемым полям универсальной модели события выполняется по их семейству cs
.
cs:email != "test@example.com"
Запрос выдаст события, для которых одновременно выполняются следующие условия:
-
Ни одно из полей значений семейства
cs
не содержит значениеtest@example.com
. -
Поле метки, соответствующее полю значений семейства
cs
, содержит названиеemail
.
Представленный запрос эквивалентен следующему запросу:
(cs1 != "test@example.com" AND cs1Label = "email") OR (cs2 != "test@example.com" AND cs2Label = "email") OR (cs3 != "test@example.com" AND cs3Label = "email") OR (cs4 != "test@example.com" AND cs4Label = "email") OR (cs5 != "test@example.com" AND cs5Label = "email") OR (cs6 != "test@example.com" AND cs6Label = "email")
Использование фильтров и ограничений по времени
После выполнения запроса в разделе Поиск можно отфильтровать возвращенные результаты с помощью кнопки Добавить фильтр. В окне добавления фильтра указывается поле, по которому проводится фильтрация, оператор сравнения и значение для сравнения.
Вместе с фильтрами удобно использовать функциональность ограничения запроса по времени. Это ограничение аналогично добавлению к запросу компонента, который ограничивает результаты запроса определенным временным интервалом.
Система воспринимает применяемые фильтры и ограничения по времени как дополнительные условия оператора WHERE
, присоединяемые оператором AND
. Переключатель Инвертировать (NOT) интерпретируется как оператор NOT
.
Примеры использования фильтров и ограничения по времени
Пример 1
Вы ввели в строке поиска запрос tenantId LIKE 'n%' AND length(raw) > 10
. Затем добавили фильтр по полю originalTimestamp
c оператором =
и значением 05.05.2023б 05:00:00
. Последовательность этих действий равнозначна следующему запросу в строке поиска:
tenantId LIKE 'n%' AND length(raw) > 10 AND originalTimestamp = '2023.05.05 05:00:00'
Пример 2
Вы хотите ограничить результат запроса tenantId LIKE 'n%' AND length(raw) > 10
датами 01.01.2023
и 12.12.2023
.
Для этого после выполнения запроса выберите значение Задать период в поле периода и укажите диапазон периода в полях справа. Эти действия аналогичны следующему запросу:
tenantId LIKE 'n%' AND length(raw) > 10 AND (timestamp >= 2023.01.01 AND timestamp <= 2023.12.12)
Таким образом, применение фильтров и ограничений по времени существенно упрощает создание поисковых запросов в системе.
Группировка (оператор GROUP BY)
Объединять результаты запроса по одному или нескольким полям можно с помощью оператора GROUP BY
. С оператором GROUP BY
могут применяться агрегатные функции: count()
, sum()
, avg()
, max()
, min()
.
SELECT {expression} GROUP BY field_name
При использовании оператора GROUP BY необходимо указать, к какой проекции будет применяться объединение. Например, запрос вида GROUP BY tenantID воспринимается системой как SELECT * GROUP BY tenantID , и поэтому некорректен. Корректный запрос с указанной проекцией имеет вид SELECT tenantID GROUP BY tenantID .
|
Сортировка возвращаемых записей (оператор ORDER BY)
Результаты запроса можно сортировать по любому полю с помощью оператора ORDER BY
.
[SELECT {expression}] ORDER BY field_name [ASC | DESC]
Направление сортировки задается модификаторами:
-
ASC
— по возрастанию; -
DESC
— по убыванию.
Примеры сортировки
ORDER BY collectorId
Этот запрос выводит события с сортировкой по полю collectorId
в порядке возрастания.
count()
SELECT tenantId, count(*) ORDER BY tenantId ASC
Этот запрос возвращает события, упорядоченные по возрастанию значения в поле tenantId
и указанием количества событий в каждой группе.
Заполнение пропусков в списке возвращаемых результатов (модификатор WITH FILL)
Чтобы заполнить пропуски в списке возвращаемых результатов при сортировке и группировке записей, используйте модификатор WITH FILL
. Пропуски заполняются значениями с указанным шагом в указанном промежутке, либо по умолчанию.
WITH FILL можно применять только после имени колонки в ORDER BY . Допускается использование нескольких WITH FILL для разных колонок.
|
SELECT {expression} ORDER BY field_name WITH FILL [FROM {expression} TO {expression}] STEP {expression}]]
Для случая с несколькими полями ORDER BY field2 WITH FILL, field1 WITH FILL порядок заполнения будет соответствовать порядку полей в секции ORDER BY .
|
Здесь:
-
field_name
— имя поля, по которому происходит сортировка. -
FROM +{expression}+
— начальное значение интервала, который будет заполнен. Если не указано, будет использовано наименьшее значение в полеfield_name
. -
TO +{expression}+
— конечное значение. Если не указано, будет использовано наибольшее значение в полеfield_name
. -
STEP +{expression}+
— шаг, с которым будет заполняться интервал. Если не указан, используется значение1.0
для числовых типов, и 1 секунда для метки времени.
Значение параметра {expression}
должен принадлежать к одному из следующих типов:
-
числовой литерал (целое или дробное число);
-
метка времени;
-
арифметическая операция с числами, меткой времени, интервалом или функцией;
-
функция с возвращаемым значением в виде числа или метки времени.
Примеры заполнения пропусков
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt GROUP BY ts HAVING sum_cnt > 0 ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
Данный запрос выполняет следующую последовательность операций:
-
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt
: выбираются значения поляtimestamp
, округленные до начала каждого часа, и вычисляется сумма поляcnt
для каждой группы записей с одинаковым значениемts
. -
GROUP BY ts
: результаты группируются по полюts
, которое представляет округленные значения. -
HAVING sum_cnt > 0
: применяется фильтрация, чтобы оставить только те группы записей, у которых сумма поляcnt
больше нуля. Это означает, что в результирующем наборе будут только записи, для которых существуют записи с положительными значениямиcnt
внутри группы. -
ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
: результаты сортируются по полюts
. Здесь используется модификаторWITH FILL
, который обеспечивает заполнение пропущенных интервалов с шагом в 1 час от текущего времени минус 1 день до текущего времени. То есть, если в исходных данных отсутствуют записи для определенных интервалов времени, то они будут включены в результирующий набор со значениями по умолчанию.
SELECT toStartOfHour(timestamp) as ts, sum(cnt) as sum_cnt GROUP BY ts HAVING sum_cnt > 0 AND ts >= now() - INTERVAL 1 day AND ts <= now() ORDER BY ts WITH FILL FROM now() - INTERVAL 1 day TO now() STEP INTERVAL 1 hour
Здесь выполняются те же самые операции, что и в первом запросе, но добавляется дополнительный фильтр в выражении HAVING
и выражении AND
. Этот фильтр ограничивает результаты только записями, у которых поле ts
находится в интервале от текущего времени минус 1 день до текущего времени. Таким образом, данный запрос дополнительно фильтрует записи по временному интервалу перед применением сортировки и заполнением пропущенных интервалов.
В результате выполнения этого запроса будет получен отсортированный список, где каждая запись будет содержать округленное значение timestamp
, сумму cnt
для соответствующей группы записей, а также пропущенные интервалы времени со значениями по умолчанию, если таковые имеются. В результирующем наборе будут только записи, удовлетворяющие условиям фильтрации по сумме cnt
и временному интервалу.
Работа с активными списками (операторы JOIN и ENRICH)
Данные можно обогащать и фильтровать через активные списки с помощью операторов JOIN
и ENRICH
:
-
В режиме базового поиска для фильтрации записей по данным активных списков используется оператор
JOIN
, который позволяет уточнить результаты запросов на основе совпадения данных без их обогащения. ОператорENRICH
используется в комбинации сJOIN
и позволяет обогащать эти результаты данными из активных списков. Поддерживаются операцииINNER JOIN
иLEFT JOIN
. -
В режиме продвинутого поиска для объединения данных из активных списков с событиями из хранилища с целью обогащения информации используется оператор
JOIN
. Поддерживаются операцииINNER JOIN
,LEFT JOIN
,RIGHT JOIN
иFULL JOIN
.
Работа с оператором JOIN в режиме базового поиска
В режиме базового поиска раздела Поиск оператор JOIN
служит для фильтрации записей на основе данных из активных списков. Это позволяет детализировать результаты запросов путем анализа совпадений значений полей без обогащения событий. При этом данные из хранилища событий и активные списки рассматриваются как отдельные таблицы: хранилище событий является "левой таблицей", а активный список — "правой".
(INNER | LEFT) JOIN `{active_list_name}` [AS alias_name] ON {expression}
Здесь:
-
(INNER | LEFT)
указывает на тип операцииJOIN
:-
INNER JOIN
отбирает строки при наличии совпадения данных между обеими таблицами. -
LEFT JOIN
отображает все строки из левой таблицы (хранилище событий), дополняя их совпадающими данными из правой таблицы (активный список), если таковые имеются. Применяется совместно с операторомENRICH
.
-
-
`{active_list_name}`
обозначает имя активного списка, который используется в качестве правой таблицы для операцииJOIN
.Имя активного списка необходимо заключать в обратные апострофы. -
AS alias_name
предоставляет возможность задать псевдоним для активного списка, упрощая дальнейшее обращение к данным в запросе. -
{expression}
формулирует условие объединения, используя операции сравнения и логические операторы для определения совпадений данных между таблицами.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в хранилище событий. Если поле в хранилище событий не найдено, поиск поля продолжается в активном списке.
Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Пример использования INNER JOIN
для фильтрации событий
Оператор INNER JOIN
в разделе Поиск может быть использован для фильтрации записей, позволяя ограничить выборку событий на основе соответствия условиям, заданным для данных из активных списков. Этот механизм не обогащает данные событий новой информацией, но позволяет исключить из результата те события, которые не соответствуют заданным критериям.
Пример запроса ниже демонстрирует использование INNER JOIN
для фильтрации событий по списку угроз threat_list
, исключая из результатов все события, не соответствующие IP-адресам, занесенным в этот список. Цель запроса — идентифицировать потенциально вредоносную активность, происходящую с IP-адресов, указанных в списке угроз.
INNER JOIN `threat_list` ON sourceIp = `threat_list`.ip_address
Этот запрос исключит из результата все события, источник которых не совпадает с IP-адресами, указанными в активном списке threat_list
. Таким образом, анализ будет сосредоточен исключительно на событиях, источник которых был заранее классифицирован как потенциальная угроза. Поскольку объединение данных не происходит, в результатах запроса отображаются только поля исходных событий, соответствующих условиям фильтрации.
Работа с оператором JOIN в режиме продвинутого поиска
В режиме продвинутого поиска раздела Поиск оператор JOIN
позволяет объединять данные из активных списков и хранилища событий, обогащая информацию о событиях. Поддерживаются операции INNER JOIN
, LEFT JOIN
, RIGHT JOIN
и FULL JOIN
, каждая из которых имеет свои особенности при объединении данных. При этом события хранилища и записи активных списков анализируются как данные в двух разных таблицах: хранилище событий служит "левой таблицей", а активный список — "правой".
[SELECT {expression}] (INNER | LEFT | RIGHT | FULL) JOIN `{active_list_name}` [AS alias_name] ON {expression}
Здесь:
-
(INNER | LEFT | RIGHT | FULL)
определяет тип операцииJOIN
, применяемой для объединения данных из левой таблицы (хранилища событий) и правой (активного списка):-
INNER JOIN
выбирает строки, где присутствует совпадение по заданным условиям в обеих таблицах. -
LEFT JOIN
отображает все строки из левой таблицы, дополняя их данными из правой таблицы при наличии совпадений. -
RIGHT JOIN
аналогиченLEFT JOIN
, но выводит все строки из правой таблицы, дополняя их данными из левой таблицы при наличии совпадений. -
FULL JOIN
объединяет методыLEFT JOIN
иRIGHT JOIN
, показывая все строки из обеих таблиц.
-
-
`{active_list_name}`
обозначает имя активного списка, который используется в качестве правой таблицы.Имя активного списка необходимо заключать в обратные апострофы. -
[AS alias_name]
позволяет назначить псевдоним активному списку, упрощая дальнейшую работу с запросом. -
{expression}
условие для объединения, которое может включать операции сравнения и логические операторы, для определения критериев совпадения данных между таблицами.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в хранилище событий. Если поле в хранилище событий не найдено, поиск поля продолжается в активном списке. Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Примеры использования JOIN
в продвинутом поиске
Пример 1. Использование INNER JOIN
Оператор INNER JOIN
может быть использован для объединения данных о событиях с активными списками, что позволит идентифицировать события, исходящие с IP-адресов, внесенных в список блокировки.
Пример запроса ниже демонстрирует использование INNER JOIN
для соединения данных событий с активным списком blacklist_ips
по IP-адресу источника (sourceIp
), с целью выявления событий с блокированными IP-адресами.
SELECT sourceIp, timestamp, action, ip_address
INNER JOIN `blacklist_ips` ON sourceIp = `blacklist_ips`.ip_address
Визуализация ожидаемого результата запроса:
event.sourceIp | event.timestamp | event.action | blacklist_ips.ip_address |
---|---|---|---|
192.0.2.1 |
2022-07-01T12:00:00Z |
Blocked |
192.0.2.1 |
192.0.2.2 |
2022-07-02T12:00:00Z |
Blocked |
192.0.2.2 |
В этой таблице отображаются события, произошедшие с IP-адресов, указанных в системе (event
), и соответствующие IP-адресам в активном списке blacklist_ips
. Используя INNER JOIN
, выборка ограничивается событиями, источники которых находятся в списке блокировки.
Пример 2. Использование LEFT JOIN
Оператор LEFT JOIN
может быть использован для объединения данных о событиях входа в систему с информацией о пользователях из активного списка. Это позволяет получить расширенный контекст активности пользователей, включая отсутствие событий для определенных пользователей. В случаях, когда соответствующая запись в активном списке отсутствует, результатом объединения для данной записи события будут значения NULL
в полях, предназначенных для данных из активного списка.
Пример запроса ниже демонстрирует использование LEFT JOIN
для соединения событий с записями активного списка о пользователях user_info
по идентификатору пользователя. Цель — включить в анализ всех пользователей, включая тех, по которым отсутствуют данные о событиях входа.
SELECT sourceIp, timestamp, ip_address, userName
LEFT JOIN `user_info` ON userId = `user_info`.user_id
Визуализация ожидаемого результата запроса:
event.sourceIp | event.timestamp | user_info.ip_address | user_info.userName |
---|---|---|---|
192.0.2.1 |
2022-07-01T12:00:00Z |
192.0.2.1 |
Sergey |
192.0.2.2 |
2022-07-02T12:00:00Z |
192.0.2.2 |
John |
192.0.2.3 |
2022-07-03T12:00:00Z |
NULL |
NULL |
В этой таблице показаны все попытки входа пользователей, зафиксированные в системе (event
), дополненные информацией о них из активного списка user_info
. Последняя строка демонстрирует случай, когда в таблице событий имеются данные о входе с IP-адреса 192.0.2.3, но информация о пользователе, выполнившем вход, отсутствует в активном списке user_info
.
Пример 3. Использование RIGHT JOIN
Оператор RIGHT JOIN
может быть применен для объединения информации об устройствах из активного списка с данными о событиях, позволяя анализировать данные обо всех устройствах независимо от наличия связанных с ними событий. В случаях, когда соответствующая запись в хранилище отсутствует, результатом объединения для данной записи события будут значения NULL
в полях, предназначенных для данных из хранилища.
Пример запроса ниже демонстрирует использование RIGHT JOIN
для соединения информации об устройствах из активного списка device_info
с данными о событиях на основе совпадения серийных номеров устройств (serial_number
) с внешними идентификаторами устройств в событиях (deviceExternalId
). Цель — предоставить полный обзор по всем устройствам, включая те, по которым отсутствуют события.
RIGHT JOIN `device_info` ON deviceExternalId = `device_info`.serial_number
Визуализация ожидаемого результата запроса:
event.deviceExternalId | event.action | device_info.serial_number | device_info.device_name |
---|---|---|---|
12345 |
Alert |
12345 |
DeviceA |
NULL |
NULL |
67890 |
DeviceB |
В этой таблице отображается информация об устройствах из активного списка device_info
, дополненная данными о событиях из системы. Запись устройства DeviceB
демонстрирует случай, когда для устройства нет зарегистрированных событий.
Пример 4. Использование FULL JOIN
Оператор FULL JOIN
можно использовать для комплексного анализа данных, чтобы объединить информацию о событиях с данными из активных списков, не исключая записи без взаимных соответствий. Это обеспечивает возможность анализа, включая изучение как связанных, так и независимых данных событий и элементов активных списков.
Пример запроса ниже иллюстрирует использование FULL JOIN
для объединения данных о событиях с информацией из активного списка network_segments
на основе соответствия между IP-адресами устройств (deviceIp
) и сегментами сети (segment_ip
). Цель — предоставить полный обзор сетевой активности и конфигурации сети, включая события и сетевые сегменты, которые прямо не связаны.
FULL JOIN `network_segments` ON deviceIp = `network_segments`.segment_ip
Визуализация ожидаемого результата запроса:
event.deviceIp | event.action | network_segments.segment_ip | network_segments.segment_name |
---|---|---|---|
198.51.100.1 |
Access_Granted |
198.51.100.1 |
Office_Network |
NULL |
NULL |
198.51.100.1 |
Data_Center |
203.0.113.24 |
Unauthorized_Access |
NULL |
NULL |
В этой таблице представлена информация, объединяющая события сетевой активности и конфигурацию сетевых сегментов. Запись для сегмента Data_Center
показывает сетевой сегмент без зарегистрированных событий, тогда как запись для IP-адреса 203.0.113.24
демонстрирует событие, для которого нет соответствующего сегмента сети в активном списке.
Работа с оператором ENRICH
Оператор ENRICH
дает возможность заменять или добавлять значения в полях событий на основе данных из соответствующих записей активного списка. Он используется в сочетании с оператором JOIN
. ENRICH
применяется только после того, как условие соединения, заданное в JOIN
, будет выполнено.
[SELECT {expression}]
(INNER | LEFT | RIGHT | FULL) JOIN `{active_list_name}` ON {join_condition}
ENRICH {target_field} = {source_field}
Здесь:
-
`{active_list_name}`
— имя активного списка, данные из которого используются для обогащения.Имя активного списка необходимо заключать в обратные апострофы. -
{join_condition}
— условие соединения, определяющее правила поиска совпадений между данными событий и записями в активном списке.При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля в хранилище событий. Если поле в хранилище событий не найдено, поиск поля продолжается в активном списке. Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
-
{target_field}
— поле в записях событий, для которого будет выполнено обогащение.Обращение к полю в записях событий может выполняться одним из следующих способов:
-
Указание только названия поля. Рекомендуется использовать данный способ, так как поиск полей по умолчанию начинается в "левой" таблице (хранилище событий).
-
Указание имени таблицы из БД ClickHouse и названия поля. Имя таблицы ClickHouse, связанной с хранилищем событий, необходимо заключать в обратные апострофы, например:
`clickhouse_table_name`.field
.Использование имени хранилища событий вместо имени ассоциированной с ним таблицы ClickHouse не допускается.
-
-
{source_field}
— поле в активном списке, значения из которого используются для обогащения данных событий.Обращение к полю активного списка может выполняться одним из следующих способов:
-
Указание только названия поля. Данный способ допустим только в тех случаях, когда в записях событий отсутствует поле с таким же названием. В противном случае произойдет обращение к полю в записях событий.
-
Указание имени активного списка и названия поля. Имя активного списка необходимо заключать в обратные апострофы, например:
`active_list_name`.field
. -
Указание псевдонима активного списка и названия поля. Псевдоним (alias) активного списка допускается задавать как с обратными апострофами, так и без них, например:
`alias_name`.field
илиalias_name.field
.
-
Оператор ENRICH
позволяет обогащать данные событий из нескольких активных списков в рамках одного запроса. Для точного указания полей из конкретных активных списков следует использовать полное имя поля, включающее имя активного списка и имя поля, разделенные точкой.
Примеры использования ENRICH
Пример 1. Обогащение данных события значениями из одного активного списка
LEFT JOIN `user_info` ON userId = `user_info`.name
ENRICH id = `user_info`.age
В данном примере запрос обогащает значение поля id
в записях событий значением поля age
из активного списка user_info
, если значение поля userId
события совпадает с полем name
в активном списке.
Пример 3. Использование INNER JOIN
с ENRICH
для обогащения событий
Применение запросов с INNER JOIN
и ENRICH
в разделе Поиск позволяет обогатить данные событий дополнительными данными из активных списков при условии точного совпадения между записями событий и данными активного списка. В отличие от LEFT JOIN
, INNER JOIN
выбирает только те записи, для которых существуют совпадающие данные в обеих таблицах, и далее ENRICH
используется для обогащения этих данных.
Этот метод подходит для сценариев, где необходимо ограничить анализ событиями, которые имеют прямое соответствие в активных списках, и одновременно обогатить эти события дополнительной информацией из этих списков. |
INNER JOIN `device_info` ON deviceId = `device_info`.device_id
ENRICH deviceType = `device_info`.type
Пример 3. Обращение к нескольким активным спискам
SELECT id
LEFT JOIN `admin_list` ON userId = `admin_list`.user_id
LEFT JOIN `security_events` ON eventCode = `security_events`.code
ENRICH adminName = `admin_list`.name, securityLevel = `security_events`.level
В данном примере запрос обогащает данные событий, используя информацию из двух разных активных списков — admin_list
и security_events
. Оператор ENRICH
применяется для замены (или добавления, если такого поля нет) в записях событий: значения поля adminName
на основании данных об имени администратора из списка admin_list
и значения поля securityLevel
на основании уровня безопасности из списка security_events
. Оба обогащения основываются на совпадении условий: userId
с user_id
для списка администраторов и eventCode
с code
для событий.
Максимальное количество и пропуск возвращаемых записей (операторы LIMIT и OFFSET)
По умолчанию в списке результатов поискового запроса отображается 500 записей. Однако вы можете ограничить количество возвращаемых записей с помощью оператора LIMIT
.
LIMIT {m} [OFFSET {n}]
Например, чтобы ограничить выдачу двадцатью записями, используется запрос:
LIMIT 20
Также можно добавить команду OFFSET
, которая указывает, сколько строк необходимо пропустить перед началом вывода. Это полезно, если вы хотите начать вывод данных с определенной строки. Например, чтобы пропустить первые 10 строк и вывести следующие 20, используется запрос:
LIMIT 20 OFFSET 10