Afilters: Difference between revisions

From Svacer Wiki
m (minor fixes after partial review)
Line 1: Line 1:
== Advanced filters ==
= Advanced filters =
Поле "Расширенный фильтр" в пользовательских фильтрах предназначено для фильтрации маркеров (предупреждений) по сложным предикатам.  
Поле "Расширенный фильтр" в пользовательских фильтрах предназначено для фильтрации маркеров (предупреждений) по сложным предикатам.  
[[File:Image-afilters-prop.png|thumb]]
[[File:Image-afilters-prop.png|thumb]]
Line 5: Line 5:


* поля маркера, его трассы, разметки и комментариев
* поля маркера, его трассы, разметки и комментариев
* информацию из контекста (имя проекта, ветки, снимка и т.п.)
* информацию из контекста: имя проекта, ветки, снимка и т. п.
* атрибуты снимка (включая пользовательские атрибуты, заданные при импорте)
* атрибуты снимка, включая пользовательские атрибуты, заданные при импорте
* статусы разметки
* статусы разметки
* текст и атрибуты комментариев
* текст и атрибуты комментариев


Формат фильтра определяется следующим шаблоном:
Формат фильтра определяется следующим шаблоном:
  <code>filter(markers, <predicate expr> )</code>
 
  filter(markers, <predicate expr>)
 
Выражение <code><predicate expr></code> определяет предикат. Объект <code>markers</code> содержит массив маркеров из контекста, функция <code>filter</code> фильтрует данный список по предикату. Таким образом, применение фильтра заключается в фильтрации списка маркеров по указанному предикату.
Выражение <code><predicate expr></code> определяет предикат. Объект <code>markers</code> содержит массив маркеров из контекста, функция <code>filter</code> фильтрует данный список по предикату. Таким образом, применение фильтра заключается в фильтрации списка маркеров по указанному предикату.


Line 18: Line 20:
=== Поля маркера (предупреждения) ===
=== Поля маркера (предупреждения) ===


* <code>Comments</code> - список комментариев маркера. Объект типа Comment (смотреть ниже)
* <code>Comments</code> список комментариев маркера. Объект типа Comment (смотрите ниже)
* <code>Details</code> - информация, специфичная для анализатора. Ближайший аналог - fingerprint в SARIF
* <code>Details</code> информация, специфичная для анализатора. Ближайший аналог fingerprint в SARIF
* <code>File</code> - имя файла
* <code>File</code> имя файла
* <code>Function</code> - имя функции, может быть managled для С++
* <code>Function</code> имя функции, может быть mangled для С++
* <code>ID</code> - UUID маркера
* <code>ID</code> UUID маркера
* <code>Invariant</code> - инвариант маркера. Используется для авто-переноса разметки между снимками
* <code>Invariant</code> инвариант маркера. Используется для автопереноса разметки между снимками
* <code>Lang</code> - язык детектора
* <code>Lang</code> язык детектора
* <code>Line</code> - номер строки в файле
* <code>Line</code> номер строки в файле
* <code>LocID</code> - порядковый номер маркера относительно изначального отчета анализатора
* <code>LocID</code> порядковый номер маркера относительно изначального отчета анализатора
* <code>MTid</code> - шаблон сообщения
* <code>MTid</code> шаблон сообщения
* <code>Msg</code> - текст сообщения
* <code>Msg</code> текст сообщения
* <code>OrigFunc</code> - 'человекочитаемое' имя функции. Может быть недоступно
* <code>OrigFunc</code> 'человекочитаемое' имя функции. Может быть недоступно
* <code>Tags</code> - список тэгов(меток) маркера
* <code>Tags</code> список тегов (меток) маркера
* <code>Tool</code> - модуль анализатора, ответственного за данный детектор
* <code>Tool</code> модуль анализатора, ответственного за данный детектор
* <code>Traces</code> - список трасс маркера. Объект типа Trace (смотреть ниже)
* <code>Traces</code> список трасс маркера. Объект типа Trace (смотрите ниже)
* <code>WarnClass</code> - название детектора/класса детекторов
* <code>WarnClass</code> название детектора/класса детекторов
 
Имена полей также могут использоваться в формате, где первая буква в lowercase.
 
Помимо использования полей, можно использовать вспомогательные функции для доступа к дополнительной информации:


Имена полей могут так же использоваться в формате, где первая буква в lower-case.
* <code>severity(item) string</code> — серьезность детектора (чекера)


Помимо использования полей, пользователь может использовать вспомогательные функции для доступа к дополнительной информации:
Пример:
<code>severity(item) string - серьезность детектора (чекера).
 
  Пример: filter(markers, severity(#) == "Critical")</code>
  filter(markers, severity(#) == "Critical")
'''Внимание:''' Использование в предикатах поля <code>Trace</code> может сказаться на скорости применения фильтра, т.к загрузка большого числа трасс может занять время.
 
'''Внимание:''' использование в предикатах поля <code>Trace</code> может сказаться на скорости применения фильтра, т. к. загрузка большого числа трасс может занять время.


=== Данные о разметке ===
=== Данные о разметке ===
Поддерживаются следующие функции для получения информации о разметки:
Поддерживаются следующие функции для получения информации о разметке:


* <code>status(item) string</code> - статус разметки текущего маркера. Пример: <code>filter(markers, status(#) == "Confirmed")</code>
* <code>status(item) string</code> статус разметки текущего маркера. Пример: <code>filter(markers, status(#) == "Confirmed")</code>
* <code>action(item) string</code> - статус поля action текущего маркера.  Пример: <code>filter(markers, action(#) == "Ignore")</code>
* <code>action(item) string</code> статус поля action текущего маркера.  Пример: <code>filter(markers, action(#) == "Ignore")</code>
* <code>mseverity(item) string</code> - статус поля severity текущего маркера (не путать с severity детектора).  Пример: <code>filter(markers, mseverity(#) == "Critical")</code>
* <code>mseverity(item) string</code> статус поля severity текущего маркера (не путать с severity детектора).  Пример: <code>filter(markers, mseverity(#) == "Critical")</code>
* <code>triaged(item) bool</code> - возвращает true, если маркер имеет не дефолтную разметку. Пример: <code>filter(markers, triaged(#))</code>
* <code>triaged(item) bool</code> возвращает true, если маркер имеет не дефолтную разметку. Пример: <code>filter(markers, triaged(#))</code>
* <code>get_triaged_by(item) UserInfo</code> - возвращает структуру, с информацией о пользователе, кто произвел разметку
* <code>get_triaged_by(item) UserInfo</code> возвращает структуру с информацией о пользователе, кто произвел разметку


Поля структуры <code>UserInfo</code>:
Поля структуры <code>UserInfo</code>:


* <code>login: string</code> - логин юзера
* <code>login: string</code> логин пользователя
* <code>create_ts: Time (UTC)</code> - время разметки в <code>UTC</code> формате (RFC3339)
* <code>create_ts: Time (UTC)</code> время разметки в UTC формате (RFC3339)


=== Комментарии ===
=== Комментарии ===
Объекты типа <code>Comment</code> содержатся в поле <code>Comments</code> маркера. Объект имеет следующие поля:
Объекты типа <code>Comment</code> содержатся в поле <code>Comments</code> маркера. Объект имеет следующие поля:


* <code>ID</code> - UUID комментария
* <code>ID</code> UUID комментария
* <code>Text</code> - текст комментария
* <code>Text</code> текст комментария
* <code>CreatedBy</code> - имя пользователя, кто создал комментарий
* <code>CreatedBy</code> имя пользователя, кто создал комментарий
* <code>CreateTs</code> - время создания комментария (объект типа <code>time.Time</code>)
* <code>CreateTs</code> время создания комментария (объект типа <code>time.Time</code>)
* <code>UpdateTs</code> - время обновления комментария (объект типа <code>time.Time</code>), может быть пустым
* <code>UpdateTs</code> время обновления комментария (объект типа <code>time.Time</code>), может быть пустым
* <code>UpdatedBy</code> - имя пользователя, кто обновил комментарий
* <code>UpdatedBy</code> имя пользователя, кто обновил комментарий


=== Трассы ===
=== Трассы ===
Маркер может содержать трассу маркера в поле <code>Traces</code>. Трасса описывается следующими структурами:
Маркер может содержать трассу маркера в поле <code>Traces</code>. Трасса описывается следующими структурами:
  <code>type Trace struct {
  type Trace struct {
  Role      string
  Role      string
  Locations []TraceEntry
  Locations []TraceEntry
Line 77: Line 84:
  Col  uint32
  Col  uint32
  Info string
  Info string
  }</code>
  }
Доступ к полям объекта <code>Trace</code> может выполняться используя правила языка <code>go-expr</code>, описанные ниже.


Имена полей могут использоваться в виде как описано выше, либо в формате lower-case: <code>role, locations, file, line, col, info</code>
Доступ к полям объекта <code>Trace</code> может выполняться, используя правила языка <code>go-expr</code>, описанные ниже.
 
Имена полей могут использоваться в виде как описано выше, либо в формате lowercase: <code>role, locations, file, line, col, info</code>


Пример:
Пример:
  <code>filter(markers, any(.Comments, .Text == "Test") &&
  filter(markers, any(.Comments, .Text == "Test") &&
  any(.Traces, any(.Locations, .Info == "Boolean expression has constant value"))
  any(.Traces, any(.Locations, .Info == "Boolean expression has constant value"))
  )</code>
  )


=== Поля снимка ===
=== Поля снимка ===
Для доступа к полям снимка пользователь может использовать переменную <code>snapshot</code>. Переменная имеет тип структуры со следующими полями
Для доступа к полям снимка можно использовать переменную <code>snapshot</code>. Переменная имеет тип структуры со следующими полями
  <code>struct {
 
  struct {
  ID              string                 
  ID              string                 
  Name            string                 
  Name            string                 
Line 101: Line 110:
  CreateTime      time.Time             
  CreateTime      time.Time             
  SourcesAvailable bool                   
  SourcesAvailable bool                   
  }</code>
  }
Имена полей могут использоваться в виде, где первая буква в lower case.
Имена полей могут использоваться в виде, где первая буква в lowercase.


Объекты в поле <code>Details</code> можно просмотреть нажав на <code>View JSON</code> кнопку в WebUI в поле <code>Snapshot Information</code>.
Объекты в поле <code>Details</code> можно просмотреть, нажав на кнопку <code>View JSON</code> в WebUI в поле <code>Snapshot Information</code>.


Пример:
Пример:
  <code>filter(markers,  
  filter(markers,  
     snapshot.buildObject == "5b634b75422bd554a8569cc10bfadc3aea77b73e" &&
     snapshot.buildObject == "5b634b75422bd554a8569cc10bfadc3aea77b73e" &&
     .warnClass matches "DEREF"
     .warnClass matches "DEREF"
  )</code>
  )


= Описание языка предикатов =
== Описание языка предикатов ==
Для написания предикатов используется язык '''Expr'''. Детальное описание всех возможностей можно найти здесь: https://github.com/expr-lang/expr  
Для написания предикатов используется язык '''Expr'''. Детальное описание всех возможностей можно найти здесь: https://github.com/expr-lang/expr  


Далее описываются конструкции, наиболее подходящие для написания правил фильтрации.
Далее описываются конструкции, наиболее подходящие для написания правил фильтрации.


== Литералы ==
=== Литералы ===
  <code>Comment /* */ or //
  Comment /* */ or //
  Boolean true, false
  Boolean true, false
  Integer 42, 0x2A, 0o52, 0b101010
  Integer 42, 0x2A, 0o52, 0b101010
Line 125: Line 134:
  Array [1, 2, 3]
  Array [1, 2, 3]
  Map {a: 1, b: 2, c: 3}
  Map {a: 1, b: 2, c: 3}
  Nil nil</code>
  Nil nil


=== Строки ===
=== Строки ===
Строки могут быть в одинарных и двойных кавычках. Для эскейпа использовать обратный слэш.
Строки могут быть в одинарных и двойных кавычках. Для эскейпа используйте обратный слэш.


Пример однострочного текста:
Пример однострочного текста:
    <code>"Hello\nWorld"</code>
"Hello\nWorld"
 
Пример многострочного текста:
Пример многострочного текста:
    <code>`Hello
`Hello
    World`</code>
World`
 
В многострочном тексте escape-последовательности не поддерживаются.
В многострочном тексте escape-последовательности не поддерживаются.


== Операторы ==
=== Операторы ===
  <code>Arithmetic: +, -, *, /, % (modulus), ^ or ** (exponent)
  Arithmetic: +, -, *, /, % (modulus), ^ or ** (exponent)
  Comparison: ==, !=, <, >, <=, >=
  Comparison: ==, !=, <, >, <=, >=
  Logical: not or !, and or &&, or or ||
  Logical: not or !, and or &&, or or ||
Line 147: Line 158:
  Range ..
  Range ..
  Slice [:]
  Slice [:]
  Pipe |</code>
  Pipe |


=== Операторы доступа к полю объекта ===
=== Операторы доступа к полю объекта ===
Пользователь может использовать оператор точка <code>.</code> и оператор <code>[]</code>:
Можно использовать оператор точка <code>.</code> и оператор <code>[]</code>:
     <code>user.Name
     <code>user.Name
     user["Name"]</code>
     user["Name"]</code>
Line 159: Line 170:
     "name" in {"name": "John", "age": 30}</code>
     "name" in {"name": "John", "age": 30}</code>


==== Optional chaining ====
=== Optional chaining ===
Оператор <code>?.</code> может использоваться для доступа к полю структуры или элементу отображения (map) без необходимости проверки, является ли структура или отображение равными <code>nil</code>. Если структура или отображение имеют значение <code>nil</code>, результатом выражения будет <code>nil</code>.
Оператор <code>?.</code> может использоваться для доступа к полю структуры или элементу отображения (map) без необходимости проверки, является ли структура или отображение равными <code>nil</code>. Если структура или отображение имеют значение <code>nil</code>, результатом выражения будет <code>nil</code>.


Line 167: Line 178:
     <code>author.User != nil ? author.User.Name : nil</code>
     <code>author.User != nil ? author.User.Name : nil</code>


==== Nil coalescing ====
=== Nil coalescing ===
Оператор <code>??</code> может использоваться для возврата левого операнда, если он не равен <code>nil</code>, в противном случае возвращается правый операнд.
Оператор <code>??</code> может использоваться для возврата левого операнда, если он не равен <code>nil</code>, в противном случае возвращается правый операнд.


Line 183: Line 194:
     <code>split(lower(user.Name), " ")</code>
     <code>split(lower(user.Name), " ")</code>


== Предикаты ==
=== Предикаты ===
Предикат — это выражение. Предикаты можно использовать в функциях, таких как filter, all, any, one, none и других.
Предикат — это выражение. Предикаты можно использовать в функциях, таких как filter, all, any, one, none и других.
  <code>filter(0..9, {# % 2 == 0})</code>
  <code>filter(0..9, {# % 2 == 0})</code>
Line 191: Line 202:
     <code>filter(tweets, len(.Content) > 240)</code>
     <code>filter(tweets, len(.Content) > 240)</code>


== Операции над строками ==
=== Операции над строками ===
  <code>trim(str[, chars])
  <code>trim(str[, chars])
  trimPrefix(str, prefix)
  trimPrefix(str, prefix)
Line 206: Line 217:
     <code>str matches "^regex$"</code>
     <code>str matches "^regex$"</code>


== Функции времени ==
=== Функции времени ===
Поддерживаются Go типы для времени и интервалов (<code>time.Time</code>, <code>time.Duration</code>) time package.
Поддерживаются Go типы для времени и интервалов (<code>time.Time</code>, <code>time.Duration</code>) time package.


Line 221: Line 232:
  date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "Europe/Zurich")</code>
  date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "Europe/Zurich")</code>


== Функции над массивами ==
=== Функции над массивами ===
<code>- all(array, predicate) - все объекты должны удовлетворять предикату
* <code>all(array, predicate)</code> — все объекты должны удовлетворять предикату
- any(array, predicate) - должен быть по крайней мере один объект, который удовлетворяет предикату
* <code>any(array, predicate)</code> — должен быть по крайней мере один объект, который удовлетворяет предикату
- one(array, predicate) - должен быть только один объект, который удовлетворяет предикату
* <code>one(array, predicate)</code> — должен быть только один объект, который удовлетворяет предикату
- none(array, predicate) - ни один объект не должен удовлетворять предикату
* <code>none(array, predicate)</code> — ни один объект не должен удовлетворять предикату
- find(array, predicate) - возвращает первый объект, который удовлетворяет предикату
* <code>find(array, predicate)</code> — возвращает первый объект, который удовлетворяет предикату
- findLast(array, predicate) - возвращает последний объект, который удовлетворяет предикату
* <code>findLast(array, predicate)</code> — возвращает последний объект, который удовлетворяет предикату
- count(array[, predicate]) - возвращает число объектов, удовлетворяющих предикату
* <code>count(array[, predicate])</code> — возвращает число объектов, удовлетворяющих предикату
- first(array) - первый объект из массива
* <code>first(array)</code> — первый объект из массива
- last(array) - последний объект из массива</code>
* <code>last(array)</code> — последний объект из массива
 
Примеры:
Примеры:
    <code>all(tweets, {.Size < 280})</code>
all(tweets, {.Size < 280})
 
any(tweets, {.Size > 280})
    <code>any(tweets, {.Size > 280})</code>
none(tweets, {.Size > 280})
 
find([1, 2, 3, 4], # > 2) == 3
    <code>none(tweets, {.Size > 280})</code>
findLast([1, 2, 3, 4], # > 2) == 4
 
count(users, .Age > 18)
    <code>find([1, 2, 3, 4], # > 2) == 3</code>
first([1, 2, 3]) == 1
 
last([1, 2, 3]) == 3
    <code>findLast([1, 2, 3, 4], # > 2) == 4</code>
 
    <code>count(users, .Age > 18)</code>
 
    <code>first([1, 2, 3]) == 1</code>
 
    <code>last([1, 2, 3]) == 3</code>

Revision as of 18:40, 2 December 2025

Advanced filters

Поле "Расширенный фильтр" в пользовательских фильтрах предназначено для фильтрации маркеров (предупреждений) по сложным предикатам.

Предикат может использовать:

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

Формат фильтра определяется следующим шаблоном:

filter(markers, <predicate expr>)

Выражение <predicate expr> определяет предикат. Объект markers содержит массив маркеров из контекста, функция filter фильтрует данный список по предикату. Таким образом, применение фильтра заключается в фильтрации списка маркеров по указанному предикату.

Список доступных полей

Поля маркера (предупреждения)

  • Comments — список комментариев маркера. Объект типа Comment (смотрите ниже)
  • Details — информация, специфичная для анализатора. Ближайший аналог — fingerprint в SARIF
  • File — имя файла
  • Function — имя функции, может быть mangled для С++
  • ID — UUID маркера
  • Invariant — инвариант маркера. Используется для автопереноса разметки между снимками
  • Lang — язык детектора
  • Line — номер строки в файле
  • LocID — порядковый номер маркера относительно изначального отчета анализатора
  • MTid — шаблон сообщения
  • Msg — текст сообщения
  • OrigFunc — 'человекочитаемое' имя функции. Может быть недоступно
  • Tags — список тегов (меток) маркера
  • Tool — модуль анализатора, ответственного за данный детектор
  • Traces — список трасс маркера. Объект типа Trace (смотрите ниже)
  • WarnClass — название детектора/класса детекторов

Имена полей также могут использоваться в формате, где первая буква в lowercase.

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

  • severity(item) string — серьезность детектора (чекера)

Пример:

filter(markers, severity(#) == "Critical")

Внимание: использование в предикатах поля Trace может сказаться на скорости применения фильтра, т. к. загрузка большого числа трасс может занять время.

Данные о разметке

Поддерживаются следующие функции для получения информации о разметке:

  • status(item) string — статус разметки текущего маркера. Пример: filter(markers, status(#) == "Confirmed")
  • action(item) string — статус поля action текущего маркера. Пример: filter(markers, action(#) == "Ignore")
  • mseverity(item) string — статус поля severity текущего маркера (не путать с severity детектора). Пример: filter(markers, mseverity(#) == "Critical")
  • triaged(item) bool — возвращает true, если маркер имеет не дефолтную разметку. Пример: filter(markers, triaged(#))
  • get_triaged_by(item) UserInfo — возвращает структуру с информацией о пользователе, кто произвел разметку

Поля структуры UserInfo:

  • login: string — логин пользователя
  • create_ts: Time (UTC) — время разметки в UTC формате (RFC3339)

Комментарии

Объекты типа Comment содержатся в поле Comments маркера. Объект имеет следующие поля:

  • ID — UUID комментария
  • Text — текст комментария
  • CreatedBy — имя пользователя, кто создал комментарий
  • CreateTs — время создания комментария (объект типа time.Time)
  • UpdateTs — время обновления комментария (объект типа time.Time), может быть пустым
  • UpdatedBy — имя пользователя, кто обновил комментарий

Трассы

Маркер может содержать трассу маркера в поле Traces. Трасса описывается следующими структурами:

type Trace struct {
	Role      string
	Locations []TraceEntry
}
type TraceEntry struct {
	File     string	
	Line     uint32
	Col  	 uint32	
	Info 	 string
}

Доступ к полям объекта Trace может выполняться, используя правила языка go-expr, описанные ниже.

Имена полей могут использоваться в виде как описано выше, либо в формате lowercase: role, locations, file, line, col, info

Пример:

filter(markers, any(.Comments, .Text == "Test") &&
		any(.Traces, any(.Locations, .Info == "Boolean expression has constant value"))
)

Поля снимка

Для доступа к полям снимка можно использовать переменную snapshot. Переменная имеет тип структуры со следующими полями

struct {
	ID               string                
	Name             string                
	SerialID         uint32                
	BuildObject      string                
	ResultsObject    string                
	ImportTime       time.Time             
	CreatedBy        string                
	CreatedByID      string                
	Details          map[string]any
	CreateTime       time.Time             
	SourcesAvailable bool                  
}

Имена полей могут использоваться в виде, где первая буква в lowercase.

Объекты в поле Details можно просмотреть, нажав на кнопку View JSON в WebUI в поле Snapshot Information.

Пример:

filter(markers, 
   snapshot.buildObject == "5b634b75422bd554a8569cc10bfadc3aea77b73e" &&
   .warnClass matches "DEREF"
)

Описание языка предикатов

Для написания предикатов используется язык Expr. Детальное описание всех возможностей можно найти здесь: https://github.com/expr-lang/expr

Далее описываются конструкции, наиболее подходящие для написания правил фильтрации.

Литералы

Comment /* */ or //
Boolean true, false
Integer 42, 0x2A, 0o52, 0b101010
Float 0.5, .5
String "foo", 'bar'
Array [1, 2, 3]
Map {a: 1, b: 2, c: 3}
Nil nil

Строки

Строки могут быть в одинарных и двойных кавычках. Для эскейпа используйте обратный слэш.

Пример однострочного текста:

"Hello\nWorld"

Пример многострочного текста:

`Hello
World`

В многострочном тексте escape-последовательности не поддерживаются.

Операторы

Arithmetic: +, -, *, /, % (modulus), ^ or ** (exponent)
Comparison: ==, !=, <, >, <=, >=
Logical: not or !, and or &&, or or ||
Conditional: ?: (ternary), ?? (nil coalescing), if {} else {} (multiline)
Membership:  [], ., ?., in
String:  + (concatenation), contains, startsWith, endsWith
Regex:  matches
Range ..
Slice [:]
Pipe |

Операторы доступа к полю объекта

Можно использовать оператор точка . и оператор []:

    user.Name
    user["Name"]

Оператор in

Оператор in для проверки наличия объекта в массиве или мэпе:

    "John" in ["John", "Jane"]
    "name" in {"name": "John", "age": 30}

Optional chaining

Оператор ?. может использоваться для доступа к полю структуры или элементу отображения (map) без необходимости проверки, является ли структура или отображение равными nil. Если структура или отображение имеют значение nil, результатом выражения будет nil.

Пример вида:

    author.User?.Name

значит тоже самое, что:

    author.User != nil ? author.User.Name : nil

Nil coalescing

Оператор ?? может использоваться для возврата левого операнда, если он не равен nil, в противном случае возвращается правый операнд.

Пример вида:

    author.User?.Name ?? "Anonymous"

значит тоже самое, что:

    author.User != nil ? author.User.Name : "Anonymous"

Оператор конвейера

Оператор конвейера | может использоваться для передачи результата выражения левого операнда в качестве первого аргумента выражения правого операнда.

Пример вида:

    user.Name | lower() | split(" ")

значит тоже самое, что:

    split(lower(user.Name), " ")

Предикаты

Предикат — это выражение. Предикаты можно использовать в функциях, таких как filter, all, any, one, none и других.

filter(0..9, {# % 2 == 0})
filter(tweets, {len(.Content) > 240})

Скобки можно опускать { }:

    filter(tweets, len(.Content) > 240)

Операции над строками

trim(str[, chars])
trimPrefix(str, prefix)
trimSuffix(str, suffix)
upper(str)
lower(str)
indexOf(str, substring)
lastIndexOf(str, substring)
hasPrefix(str, prefix)
hasSuffix(str, suffix)

Так же есть оператор matches для поиска регулярного выражения в строке:

    str matches "regular expression"

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

    str matches "^regex$"

Функции времени

Поддерживаются Go типы для времени и интервалов (time.Time, time.Duration) time package.

Можно использовать операции сложения и вычитания над объектами с типом time.Time.

createdAt - now()
createdAt + duration("1h")
createdAt > now() - duration("1h")
date("2023-08-14")
date("15:04:05")
date("2023-08-14T00:00:00Z")
date("2023-08-14 00:00:00", "2006-01-02 15:04:05", "Europe/Zurich")

Функции над массивами

  • all(array, predicate) — все объекты должны удовлетворять предикату
  • any(array, predicate) — должен быть по крайней мере один объект, который удовлетворяет предикату
  • one(array, predicate) — должен быть только один объект, который удовлетворяет предикату
  • none(array, predicate) — ни один объект не должен удовлетворять предикату
  • find(array, predicate) — возвращает первый объект, который удовлетворяет предикату
  • findLast(array, predicate) — возвращает последний объект, который удовлетворяет предикату
  • count(array[, predicate]) — возвращает число объектов, удовлетворяющих предикату
  • first(array) — первый объект из массива
  • last(array) — последний объект из массива

Примеры:

all(tweets, {.Size < 280})
any(tweets, {.Size > 280})
none(tweets, {.Size > 280})
find([1, 2, 3, 4], # > 2) == 3
findLast([1, 2, 3, 4], # > 2) == 4
count(users, .Age > 18)
first([1, 2, 3]) == 1
last([1, 2, 3]) == 3