JIRA seriál: #6 Nepoužívejte Basic search, naučte se JQL!

Tímto článkem navazuji na 5 předchozích dílů seriálu, který pravidelně zveřejňujeme na našem blogu. Tentokrát se zaměřím na filtry. Ty totiž v rámci možností práce s daty představují jednu z extrémně silných zbraní, která je v JIRA k dispozici. Pomocí filtrů můžeme vytáhnout data zobrazovaná v gatgetech v dashboardech, v boardech (tabulích) nebo prostě v tabelárním přehledu. V případě tabelárních přehledů navíc těžíme z faktu, že jsou parametry filtru uchovávané v GET URL. Díky tomu je možné vyfiltrované přehledy sdílet e-mailem a je možné si na ně vytvořit záložky v prohlížeči.

Filtrační kritéria je možné definovat ve výchozím módu Basic nebo lze přepnout do módu Advanced. V režimu Basic uživatel postupně „nakliká“ filtrační kritéria prostřednictvím rozbalovacích menu.

Klíčová pole jsou vidět „na první kuk“ (např. Project, Typ, Status), k ostatním se dostanete pomocí menu More. Postupné naklikávání jednotlivých kritérií je pomalé, a navíc některá pokročilejší kritéria takto ani nastavit nelze. Pokud používáte JIRA jako „power user“ na denní bázi, vyplatí se vám pracovat v pokročilém módu a zadávat filtr pomocí JQL (JIRA Query Language, jazyk velmi podobný SQL pro práci s databází). Efektivitě práce s JQL napomáhá i „našeptávač“, který v průběhu psaní zobrazí možné hodnoty vyhovující dosud zadaným znakům. Následující obrázek ukazuje příklad filtru, který není možné v základním módu zadat. Obsahuje subfiltry (velmi mocná funkce, které budu věnovat samostatný díl) a relativní určení data.

V dalším textu nebudu suplovat manuál základů práce s JQL (najdete jej na webu Atlassianu – Basic Search, Advanced Search). Základy JQL nastudujte předem “bokem”, jinak vám následující text nic nedá.

Představím vám s krátkým komentářem příklady konstrukcí, které často používám v praxi. Berte je skutečně jako příklad – ve vaší instanci JIRA dané pole nemusí existovat. Na webu Atlassianu najdete přehlednou stránku s informací, které operátory a funkce jsou pro konkrétní typy polí podporované.

Pro operátory budu v textu používat velká písmena, abych je odlišil. JIRA je ale tolerantní. Na velikosti písmen jí nezáleží v operátorech, názvech funkcí, názvech polí, ani v případě hledaného textu.

Používání IN operátoru

Operátor IN je velmi užitečný pro dohledání záznamů, kde hodnota určitého pole odpovídá aspoň jedné hodnotě ze seznamu možných.

Priority IN (Critical, Blocker)

Množinový operátor IN používám často i v případě, že aktuálně potřebuji do filtru zařadit jen jednu hodnotu z možných hodnot pro dané pole (tj. bylo by možné napsat dotaz Status=Retest).

Status IN (Retest)

Pokud v budoucnu budete přidávat další hodnoty, budete rychlejší.

Status IN (Retest, Resolved, „Ready for retest“)

Všimněte si v uvedeném příkladu uvozovek pro víceslovnou hodnotu. Ty tam musí být, jinak dotaz vrátí chybu. Doporučuji psát počáteční uvozovku rovnou před zápisem víceslovného textu, jinak nefunguje našeptávač možných hodnot po stisku mezerníku (někdo zapíše víceslovný text a pak přidává uvozovky).

Operátor IN nefunguje pro textová pole typu Description, Summary, Comments. Tam je třeba použít operátor OR s trochu „ukecanější“ syntaxí:

Summary ~ report OR Summary ~ form … filtruje položky obsahující v Summary buď „report“ nebo „form“

Používání operátoru negace NOT IN

Status NOT IN (Closed)

Použití NOT IN vede mnohdy ke kratšímu dotazu a může mít i tu výhodu, že při přidání další výčtové položky do daného pole nemusíte dotaz modifikovat. Typicky, když potřebujete vyfiltrovat neuzavřené defekty, tak se vám hodí odfiltrovat pouze stav Closed a nedefinovat dílčí stavy značící neuzavřený defekt.

Relativní filtrování datumových polí

Fantastickou možností je filtrace datumových polí prostřednictvím relativních hodnot vůči aktuálnímu času. Mnohdy se potřebujete dostat k defektům zadaným včera, defektům za poslední hodinu atd. Jak na to?

Created > -1d … filtruje položky založené za uplynulých 24h od „teď”

Updated > -2h … filtruje položky aktualizované v průběhu posledních 2h

Resolved > -4w … filtruje položky uzavřené v průběhu posledních 4 týdnů

Relativně můžete definovat počet minut (m), hodin (h), dní (d), týdnů (w), měsíců (M) a roků (y).

Relativní filtrování kalendářního dne

V praxi mnohdy chcete vidět, co v projektu přibylo včera. Vytvoření filtru na konkrétním datum není úplně to pravé ořechové. Každý den ho měnit nechcete. Použijte funkci startOfDay() a endOfDay()

Created > startOfDay(-1d) AND Created < endOfDay(-1d)

Tyto funkce vrací (vnitřně) do dotazu hodnotu data a času začátku, resp.konce včerejšího dne. Argumentem funkcí je relativní počet jednotek jako v předchozím příkladu. Pokud jednotku nezadáte, pracuje se s 0, tj. dneškem. Analogicky fungují funkce pro práci se začátkem/koncem týdne (startOfWeek())) měsíce (startOfMonth()), roku (startOfYear()).

Absolutní zadání data

Datum a čas můžete samozřejmě zadat v absolutní podobě, ale je třeba dát pozor na časový údaj. Většina polí, které JIRA zobrazuje jen jako datum, vnitřně obsahuje čas. Možné formáty zadání datového údaje do filtru jsou:

'yyyy/MM/dd HH:mm'

'yyyy-MM-dd HH:mm'

'yyyy/MM/dd'

'yyyy-MM-dd'

Pokud informaci o času nezadáte, JIRA pracuje jako byste zadali 00:00. Častou chybou je tedy filtr typu Created = 2022-12-31. Nevrátí, co se dělo v průběhu Silvestra. Vrátí obvykle prázdnou sadu – o Silvestru v čase 00:00 všichni spí a sbírají síly na další noc. 😊 Než opustíme téma datumů, připojím důležitou poznámku na závěr: Doporučuji používat notaci s pomlčkami. Pokud do dotazu nezadáváte časový údaj, nemusíte psát okolní apostrofy či uvozovky. Pokud preferujete lomítka, musíte na klávesnici spáchat dva stisky navíc.

Filtr na aktuálního uživatele

Do týmového dashboardu takřka vždy zařazuji gatget zobrazující tikety přiřazené aktuálnímu uživateli. Podkladový filtr využívá funkci currentUser().

Assignee = currentUser()

Stejnou funkci použijete, pokud chcete vypsat tikety zadané přihlášeným uživatelem:

Reporter = currentUser()

A do třetice můžete vytvořit gatget s tikety sledovanými přihlášeným uživatelem:

Watcher = currentUser()

Hledání v poli labels

Občas potřebujete vyhledat tikety, kde v poli labels nějaký řetězec není obsažen. Dotaz by mohl vypadat takto:

labels not in (after-go-live, aftergolive, after-golive)

Opravdu je správně? Spíš ne. V podobné situaci chcete i tikety, které mají labels prázdné. Ty by předchozí dotaz nevrátil. Je potřeba přidat část filtrující prázdné labels. Dotaz pak vypadá následovně:

labels not in (after-go-live, aftergolive, after-golive) OR labels IS EMPTY

Používání zástupných znaků (wild cards) v JQL

Žádný jazyk sloužící k vyhledávání se neobejde bez zástupných znaků. JQL to s nimi také umí. Výhodu mají ti z vás, kteří používají v nějakém produktu knihovnu Apache Lucene. Je použita i pro indexaci textu v JIRA polích, a proto drží JQL z pohledu zástupných znaků stejnou syntax.

Zástupné znaky můžete použít pro vyhledávání v jakémkoli textovém poli (free text, text < 255 znaků + v poli version), musíte ale vždy použít operátor ~.  Podívejme se na práci se zástupnými znaky optikou pár příkladů:

summary  ~ win* … vyfiltruje záznamy s windows, windowsXP, win95, ale i s textem “I will win.”

summary  ~  win*95 … … vyfiltruje záznamy s windows95, win95, ale už ne záznam s “I will win in 1995.”

summary  ~  “report 12?” … vyfiltruje záznamy s “report 12”, “report 124”, ale už ne záznam s “report 1258”

Při prohledávání textů je třeba dát opravdu pozor na použití operátoru ~. Pokud použijete operátor „rovná se“ = , hledá JIRA shodu celého obsahu pole se zadaným textem.

Používání operátoru WAS v kombinaci AFTER | BEFORE | BY | DURING | ON

JIRA není přeborníkem v historizaci záznamů, ale pro některé pole si historii uchovává. S historickou hodnotou můžete pracovat s využitím operátoru WAS, který je však často použit v kombinaci s operátory AFTER, BEFORE, BY, DURING a ON. Na detailní vysvětlení se podívejte na web Atlassianu, já ukážu jen pár příkladů.

status WAS Closed BY mrenda DURING ("2022/01/01","2023/01/01") … tikety uzavřené uživatelem mrenda v roce 2022

Používání operátoru CHANGED v kombinaci AFTER | BEFORE | BY | DURING | ON

Operátor CHANGED můžeme použít pro dohledávání záznamů, které se v určitém poli změnily. Opět je možné je kombinovat s operátory AFTER, BEFORE, BY, DURING a ON.

priority CHANGED BY mrenda BEFORE endOfWeek() AFTER startOfWeek() … tikety, kde uživatel mrenda změnil prioritu v průběhu aktuálního týdne

Co se dozvíte v dalším díle?

Jak používat filtr uvnitř jiného filtru pro systematické strukturování dotazů! Sledujte nás na sítích, ať vám to neunikne...

Autor: Miroslav Renda

Mirek se pohybuje v různých projektových rolích v IT byznysu více než 25 let. Posledních 8 let si v roli test managera užíval zajímavé projekty ve velkých českých bankách a v oblasti automotive. Je spolupachatelem knihy Efektivní testování softwaru vydané nakladatelstvím GRADA. Miluje své dvě děti, přírodu a sport v jakékoli podobě.