--- title: Lekérdezési nyelv menu: Lekérdezési nyelv visible: true --- Az tartalomlejátszási folyamat [állapotfájából][állapotfa] az `nxPath` lekérdezési nyelv segítségével lekérdezhetők a tanulási állapot adatai. Az így lekérdezett adatok szövegmezőben megjelenítve, vagy az eseménykezelésben az esemény feltételeként vagy paramétereként alkalmazva lehetővé teszik [reaktív][reaktív tananyag], azaz a tanuló tanulására reagáló, a tanulóhoz alkalmazkodó tananyagok létrehozását. Az állapotlekérdezés a tananyagszerkesztőben egyelőre három helyen lesz felhasználható: - Szövegmezőbe illesztve a lekérdezett eredmény, tehát például a teszt eredménye megjeleníthető. - Egy esemény feltételeként megadva az esemény akkor valósul meg, ha van a keresésnek eredménye. Például ha a tesztnek van pontszáma (szűrőfeltétellel megadható, hogy milyen pontszám szükséges), akkor megvalósul az `item show` esemény és megjelenik egy kép. Ilyenkor csak lekérdezést kell a mezőbe írni. - Paraméterként a lekérdezés eredménye az esemény működését módosítja. Például a `navigate` esemény a tesztfeladat pontszámának megfelelő oldalt lapoz előre. (Ehhez további fejlesztés szükséges, jelenleg a `navigate` esemény relatív navigáláskor csak -1, 0 és 1 értékkel működik ennek megfelelően.) Mivel a paraméter mezőbe szám is írható, ha lekérdezést használunk paraméterként, akkor azt két-két kapcsos zárójel között kell a mezőbe írni. !!!! Pl: Az oldalon szereplő teszt pontszáma, ha a teszt sikeres: `.test.result{.passed==true}.score` Eredmény: `4` === [TOC] ## Az állapotfa {{ page.find('/lcms/reaktiv/allapotfa').summary }} ## Fogalmak - **a fa mélysége:** az állapotfa mélységét vízszintes irányban értjük a jelenlegi megjelenítésben. Balról jobbra haladva mélyül a fa. A függőleges megjelenítése az adatoknak csak listaszerű, egyéb jelentéssel nem bír. - **gyökér / gyökérelem:** Az állapotfa bal szélén található elemek. Ilyen gyökérelem pl. a lesson, session, page ... - **ág / ágelem:** a gyökérelemtől indulva jobbra a következő valamelyik elem neve. Pl. ha a gyökér elem a `test`, akkor annak egy ágeleme a `result` - **levél / levélelem:** olyan elem, amitől jobbra már nem található semmi. Elemi adat (szám, szöveg, igaz/hamis). ## nxPath lekérdezés megfogalmazása Egy keresőkifejezés két részből áll: 1. A lekérdezni kívánt adatból, amely meghatározza, hogy pontosan mely információkat adja meg a rendszer válaszként, 1. valamint egy (vagy több) [szűrőfeltételből][szűrőfeltétel], amely megmondja, hogy az elérési útvonal által definiált értékek közül melyeket vagy milyen feltételekkel adjon vissza a rendszer. | elérési útvonal | szűrőfeltétel | útvonal vége | |:-----------------:|:-------------------:|:------------:| | .test.result | {.passed == true} | .score | !! A lekérdezés megfogalmazásakor figyelj a kis- és nagybetűkre! ## A lekérdezés eredménye Attól függően, hogy az elérési eredmény milyen elemre mutat, a lekérdezés eredménye lehet: - egy érték, ha az útvonal egy levélelemre mutat (pl. `.page.result.startTime`) - több érték listája, ha az útvonal több levélelemre mutat (pl. itt az összes betöltött feladat pontszámát kapjuk meg: `.exercises.result.score`) - tömb: több egyforma felépítésű (egyforma adatmezővel rendelkező) objektum (pl. `.exercises`. Tehát nem elemi adat, hanem egész objektum) - objektum: egy vagy több adatmező (levélelem) és azok értéke (pl. `.page.result`) !! **Szövegmezőben** jelenleg csak egy értéket lehet esztétikusan megjeleníteni. Listát a rendszer megjelenít, de az nem formázható, az értékek egymástól vesszővel elválasztva, szóköz nélkül jelennek meg. Tömb és objektum nem jelenik meg megfelelően. ! ! Esemény **paramétereként** csak olyan lekérdezés lesz használható, amely egyetlen értéket eredményez. Mivel először kiértékelődnek a lekérdezések és utána fut le az esemény, ezért megfogalmazható olyan paraméter, amely több lekérdezés-eredményből áll össze. ! ! Esemény **feltételeként** nem számít, hogy a lekérdezés milyen eredményt hoz, ha van eredmény (az elérési útvonal létező elemre mutat, és a szűrőfeltétel teljesül), akkor az esemény megvalósul. **Megjegyzés:** a *dataChange* trigger a megfogalmazott feltételben kapott lekérdezés eredményének minden adatát figyeli és változás esetén tüzel. Itt érdemes megfontoltan megírni a lekérdezést. Ha nem elég pontos a lekérdezés, akkor nem várt időben sülhet el az esemény. Ha pl. ez a feltétel: `@exercise.result{.evaluable == true}`, akkor az esemény minden alkalommal elsül amikor a feladat kiértékelhető és valami módosul a feladat eredmény objektumán belül (hiszen a lekérdezés a teljes feladat eredmény objektumot adja vissza). Ennek elkerülésére fontos, hogy pontos lekérdezést írjunk így: `@exercise.result{.evaluable == true}.evaluable`. Ez esetben csak az `evaluable` változás hatására fog végrehajtódni az esemény. ## Elérési útvonal Az elérési útvonallal lehet megadni azt az elemet (vagy elemeket), amelynek az értékét (vagy értékeit) le szeretnéd kérdezni. Ezt úgy tudod megadni, hogy megadod a kívánt elem elhelyezkedését, vagyis az elemet tartalmazó csomópontokat. Legutolsó csomópontként kell megadnod azt az elemet amelynek tartalmát válaszként szeretnéd kapni a keresésedre. Minden elem elé pontot `.` kell tenni. !!!! Az oldalon szereplő teszt eredményei közül a pontszámot így érheted el: `.test.result.score` !! - Ha az elérési útvonal utolsó eleme **levélelem**, akkor a lekérdezés eredménye egy vagy több érték lesz. ! - Ha az elérési útvonal utolsó eleme egy **csomópont** (olyan elem, amelyben további elemek találhatók), akkor a lekérdezés eredménye az adott csomóponton belüli fastruktúra lesz, tehát a csomópontban szereplő elemek, és az azokban szereplő elemek egészen a levélelemekig és azok értékéig. ### Több elem lekérdezése Egy lekérdezéssel több elem értékét is le lehet kérni. Ilyenkor a megjelenítendő elemeket zárójelbe `()` kell tenni, és függőleges vonallal `|` kell elválasztani őket. !!!! Az oldalon szereplő teszt eredményei közül a pontszám és a százalék: `.test.result(.score|.percent)` ### Helyettesítő karakterek használata a lekérdezési útvonalon Olyan lekérdezés is megfogalmazható, amelyben nincs megadva a teljes útvonal a gyökértől a lekérdezni kívánt elem(ek)ig, hanem az útvonal egyes csomópontjait helyettesítő karakterekkel írjuk le. A csillag `*` helyettesítő karaktert használva a struktúra egy eleme bármely elemre cserélhető. !!!! A `.nodes.*.status` lekérdezés a `.nodes` elemen belül közvetlenül lévő **bármely** elemben lekéri a státuszokat. Vagyis **minden** olyan státuszt meg fog jeleníteni, amely a `.nodes` valamelyik elemén belüli található. Ha egy helyett két pontot `..` teszel egy elem elé, akkor a befogadó elemből (vagy a gyökérből) **bármilyen mélységben** származó adott nevű elem eredményét lekérdezed, vagyis az **összes** adott elemnevű értéket. !! Figyelem! A `..` és a `*` használata nem várt lekérdezéseredményhez vezethet, hiszen nincs pontosan meghatározva, hogy melyik ág adatát szeretnénk megkapni. Ha csak lehet, kerüljük a használatukat és kellően pontos lekérdezést írjunk. Lekérdezés íráskor abba is gondoljunk bele, hogy idővel bővülhet a fa szerkezete. Ebben az esetben kérdéses, hogy egy korábban használt lekérdezés ugyanazt az eredményt adja-e. A legidőtállóbb megoldás a rövidítések használata. !!!! Például a `.nodes..status` a nodesoldalon belüli **összes** pontszámot megjeleníti.| A `*` és a `..` használata között tehát az a különbség, hogy az előbbi figyelembe veszi a lekérdezett elem helyzetét az adatstruktúrában, míg az utóbbi figyelmen kívül hagyja. Tehát a `..score` a teljes állapotfa összes pontszámát megjeleníti, míg a `.*.score` az összes második szintű (tehát bármely első szintű csomópontból leszármazott) pontszámot sorol fel ### Az útvonalban használható karakterek | karakter | karakter funkciója | |:--------:|:------------------------------------| | `.` | közvetlenül leszármazó elem | | `..` | bármely mélységben leszármazó elem | | `*` | minden (adott pozícióban lévő) elem | | `()` | több adott pozícióban lévő elem | | `@` | rövidítést jelölő elem | !! Figyelj rá, hogy a pontot mindig az adott elem neve elé, ne a befogadó elem neve után tedd! ### Rövidítések: előre definiált lekérdezések A gyakran használt lekérdezési útvonalakra rövidítéseket is bevezettünk. A `@`-cal kezdődő rövidítések használatával rövidebben, így átláthatóbban megfogalmazhatók lekérdezések. Ezen kívül, ha a jövőben módosulna az állapotfa felépítése, a rövidítésekre épülő lekérdezések továbbra is működni fognak. A működése egyszerű: ha pont helyett `@` karakterrel kezded a lekérdezést, akkor közvetlenül a kiválasztott elemhez juthatsz. Például az aktuális feladat lekérdezésére elég a `@exercise` útvonalat megadni a szintén használható `.exercises#getCurrent()` helyett. Egyszerűsítés kedvéért az aktuális elemeken kívül minden gyökérelemhez is tartozik `@`-cal kezdődő rövidítés. Így egy lekérdezés írásakor biztosak lehetünk benne, hogy az adott adat a gyökér elemtől származik (nem kell a `^` karaktert használni). Ajánlott minden lekérdezést ilyen módon megfogalmazni. A rövidítések teljes listája a következő táblázatban található. | rövidítés neve | rövidítés helye | |--------------------|:-----------------------------------| | `@session` | session gyökérelem | | `@content` | content gyökérelem | | `@lesson` | lesson gyökérelem | | `@nodes` | nodes gyökérelem | | `@node` | az aktuális *node* elem a *nodes* listában (ahol megtalálható az `isCurrent` jelölő) | | `@page` | page gyökérelem | | `@items` | items gyökérelem | | `@item` | az aktuális *item* elem az *items* listában (ahol megtalálható az `isCurrent` jelölő) | | `@test` | test gyökérelem | | `@groups` | groups gyökérelem | | `@group` | az aktuális *group* elem a *groups* listában (ahol megtalálható az `isCurrent` jelölő) | | `@exercises` | exercises gyökérelem | | `@exercise` | az aktuális *exercise* elem a *exercises* listában (ahol megtalálható az `isCurrent` jelölő) | !! Megjegyzés: ebbe a listába igény esetén fel tudunk venni más, gyakran használt lekérdezést is ## Szűrőfeltételek Az elérési útvonal bármely pontjához megadhatók szűrési feltételek. Ezek azt határozzák meg, hogy az útvonal által megjelölt elemek közül melyeket, vagy milyen feltételek mellett jelenítsen meg a keresés. !!!! Például a `.test.result{.passed==true}.score` lekérdezés megjeleníti az oldalon szereplő teszt eredményei közül a pontszámot, **de csak akkor, ha** az oldalon szereplő teszt eredménye sikeres (`passed`). ### Logikai szűrőfeltétel A logikai szűrők két módon tudják szabályozni a lekérdezést. A feltétel működhet **"ha, akkor"** módon: *ha* a logikai feltétel teljesül, *akkor* jelenítse meg az útvonal által megadott adatokat. Ha a logikai feltétel nem teljesül, akkor a lekérdezésnek nem lesz eredménye. De a logikai feltétel működhet **"az(ok), amely(ek)"** jelentéssel is, tehát az útvonal által jelölt adatok közül *azokat* jelenítse meg, *amelyek* teljesítik a logikai feltételt. A két szűrőfeltétel között csak nyelvi megfogalmazásban van különbség, a lekérdezés nyelvén egyformán működnek. A logikai szűrőfeltételt mindig kapcsos zárójelek között `{}` kell megadni. Az alábbi elemekből épül fel: - a **feltételelem**, amelynek az értéke összehasonlítás alapja - az **operátor**, ami kifejezi a viszonyt a levélelem és az érték között - és az **elvárt érték**, amellyel a lekérdezés a feltételelemet összehasonlítja. | | feltételelem | operátor | elvárt érték | | jelentés | |:--|:-------------|:--------:|:------------:|:--|:--------------------------------------| | { | .evaluated | == | true | } | a feladat vagy teszt ki van értékelve | #### Feltételelem A feltételelemet (ugyanúgy, ahogy a lekérdezni kívánt elemet) egy útvonal azonosítja. - Ha a feltételelem és a lekérdezni kívánt elem útvonala **részben azonos** akkor a közös rész a kapcsos zárójel `{}` előtt helyezkedik el. A feltételelem útvonalának azon része, amely különbözik a lekérdezett elemétől, a kapcsos zárójelen `{}` belülre kerül (a lekérdezett elem útvonalának vége pedig a logikai feltétel után). !!!! A `test.result{.passed==true}.score` példalekérdezés esetén a keresés a ! - **.test.result**{.passed==true}.score blokkban található ! - .test.result{.passed==true}.**score** értéket adja vissza, ! - abban az esetben, ha (vagy a .score értékek közül azokat, amelyeknek) a **.test.result{.passed**==true}.score értéke ! - teljesíti a .test.result{.passed**==true**}.score feltételt. - Amennyiben a **lekérdezni kívánt elem teljes útvonala megegyezik a feltételelemmel** (tehát például kérem egy feladat pontszámát, ha az a pontszám több, mint 5), akkor a levélelem (pontszám) bekerül a kapcsos zárójelbe, és megismétlődik a kapcsos zárójel után is: `{.score>5}.score` - Ha a lekérdezni kívánt elem és a feltételelem útvonalában **nincs közös csomópont**, akkor a kalap `^` karakter segítségével megadható egy abszolút (a kapcsoszárójelen `{}` kívül található útvonaltól független) útvonal, vagyis a feltételelem teljes útvonala. Mivel ilyenkor a két útvonal egymástól független, ezért a szűrőfeltétel a lekérdezési útvonal bármely eleme után beilleszthető. Erre a célra a lekérdezés rövidítések is használhatóak (`@` karakterrel jelölt elemek), hiszen azok is mindig a gyökérelemtől működnek. !!!! Például, ha az éppen aktuális feladat pontszámára van szükség abban az esetben, ha az oldalon szereplő teszt már ki van értékelve, akkor azt az alábbi lekérdezéssel lehet megjeleníteni: `@exercise.result.score{^.test.result.evaluated==true}`. ! Az `@exercise.result{^.test.result.evaluated==true}.score` `@exercise{^.test.result.evaluated==true}.result.score` `@exercise.result.score{^.test.result.evaluated==true}` és `@exercise.result.score{@test.result.evaluated==true}` lekérdezések (az abszolút elérési útvonal miatt) egymással egyenértékűek. !! Tehát amikor egy lekérdezést írsz: (Ajánlott elolvasni a [Fogalmak](#fogalmak) részt) ! 1. Azonosítsd a lekérdezni kívánt elem útvonalát balról jobbra haladva (pl. .test.result.score) ! 1. Haladj a gyökérelemtől a levél elemek irányába: A gyökérelem a `test`, annak van egy `result` objektuma és innen a `score` adatra van szükség ! 1. Ha szükség van feltételre (pl. csak akkor kell ez az adat, ha a teszt már ki van értékelve), akkor érdemes megvizsgálni, hogy hova kerüljön a feltétel. Ha a feltételt a `.test.result` után írjuk, akkor a `{}` zárójeleken belül egyszerűen elérhető a `score` adat így: `.test.result{.score > 0}`. Ha a feltételt a `score` után tesszük, akkor a zárójeleken belül már csak abszolút hivatkozással tudjuk ezt az adatot vizsgálni, hiszen a feltételt egy levél elemen vizsgáljuk így: `.test.result.score{^.test.result.score > 0}`. Az előbbi verzió egyszerűbb, érdemes azt választani. ! 1. Miután megírtuk a feltételt, ellenőrizzük, hogy a lekérdezés eredménye elég pontosan meghatározott-e. Ha nem, akkor a `}` jel után tovább lehet pontosítani a lekérdezést. #### Operátorok | Összehasonlító operátorok | leírás | példa | jelentés | |:--------------------------|:-----------------------------------------------------------------------------------------------------------|:--------------|:--------------------------| | == | a feltétel teljesül, ha a két érték megegyezik | `{.score==1}` | a pontszám 1 | | != | a feltétel teljesül, ha a két érték nem egyezik meg | `{.score!=1}` | a pontszám nem 1 | | > | a feltétel teljesül, ha a levélelem értéke nagyobb mint az elvárt érték | `{.score>1}` | a pontszám nagyobb mint 1 | | < | a feltétel teljesül, ha a levélelem értéke kisebb mint az elvárt érték | `{.score<1}` | a pontszám kisebb mint 1 | | >= / <= | a feltétel teljesül, ha a levélelem értéke nagyobb vagy egyenlő / kisebb vagy egyenlő mint az elvárt érték | `{.score>=1}` | a pontszám legalább 1 | !! Az `==` és `!=` operátorok szám-, szöveg- és logikai értékek összehasonlításakor is használhatók. !! Ha a feltételelem nem egy érték, hanem egy tömb (például az összes feladatazonosító), akkor a tömb bármely értéke teljesítheti a feltételt. Vagyis például a `.exercises{.id>13609}.id` lekérdezés feltétele megvalósul, ha van az oldalon olyan feladat, amelynek az azonosítója nagyobb mint 13609. A lekérdezés eredményeként minden feltételt teljesítő feladatazonosító megjelenik. !! Ha karakterlánc lekérdezése történik, akkor szövegösszehasonlító operátorok is használhatók. Az elvárt értéket szöveges adatemző esetén idézőjelek `""` között kell megadni. !! Az operátor elé és után lehet, de nem kötelező szóközt tenni. Azaz szóközzel elválasztva és a feltételelemekhez ragadva is működnek az operátorok | Szövegoperátorok | leírás | példa | jelentés | |:-----------------|:------------------------------------------------------------------------------------------------------|:-------------------------|:------------------------------------------------------| | ^== | a feltétel teljesül, ha az elem az elvárt értékkel kezdődik (nagybetűérzékeny) | `{.page_title^=="Első"}` | az oldal címének eleje "Első" | | ^= | a feltétel teljesül, ha az elem az elvárt értékkel kezdődik (kis- és nagybetű nem számít) | `{.page_title^="Első"}` | az oldal címének eleje "Első" vagy "első" | | $== | a feltétel teljesül, ha az elem vége az elvárt érték (nagybetűérzékeny) | `{.page_title$=="teszt"}`| az oldal címének vége "teszt" | | $= | a feltétel teljesül, ha az elem vége az elvárt érték (kis- és nagybetű nem számít) | `{.page_title$="teszt"}` | az oldal címének vége "teszt" vagy "Teszt" | | `*==` | a feltétel teljesül, ha az elem tartalmazza az elvárt értéket (nagybetűérzékeny) | `{.page_title*=="teszt"}`| az oldal címe tartalmazza a "teszt" szót | | `*=` | a feltétel teljesül, ha az elem tartalmazza az elvárt értéket (kis- és nagybetű nem számít) | `{.page_title*="teszt"}`| az oldal címe tartalmazza a "teszt" vagy "Teszt" szót |   | Logikai operátorok | leírás | példa | jelentés | |:-------------------|:--------------------------------|:--------------------------------|:---------| | ! | megfordítja a feltételt, vagyis a feltétel akkor teljesül, ha a felkiáltójel után megfogalmazott feltétel hamis. Zárójelezés használata javasolt. | `{! (.page_title*=="teszt")}` | a feltétel akkor teljesül, ha az oldal címe nem tartalmazza a "teszt" szót | | `&&` | több logikai feltételt lehet vele összekötni, és mindkét feltételnek teljesülnie kell | `{.score>1 && .result.score==1}` | a feltétel akkor teljesül, ha a feladatban elért pontszám 1 és a feladat max pontszáma 1-nél több | | `||` | több logikai feltételt lehet vele összekötni, és legalább az egyik feltételnek teljesülnie kell|`{.evaluated==true || .evaluable==true}`|a feladat kiértékelt vagy kiértékelhető | ### Matematikai műveletek Egy szűrőfeltételben a számértékekkel az **matematikai műveletek** is végrehajthatók: - összeadás`+`, - kivonás `-` - szorzás `*` - osztás `/` - maradékos osztás (az osztás maradékát adja meg eredményként) `%` !!!! A matematikai művelet eredménye önmagában nem logikai feltétel, az eredményre lehet logikai feltételt megfogalmazni az operátorok segítségével. ! Például a `.test.result{.endTime - .startTime > 19000}` logikai feltétel akkor teljesül, ha a tesztkitöltés megkezdése és befejezése közt eltelt idő 19 másodpercnél több. Tehát a `.test.result{.endTime - .startTime > 19000}.score` lekérdezés visszaadja a teszt eredményét, ha a tesztkitöltés 19 másodpercnél tovább tartott. ### Szűrés elhelyezkedés alapján Tömbön belül a lekérdezést az elem sorban elfoglalt pozíciója alapján is lehet szűkíteni, például az oldal második betöltött szakaszára, vagy a teszt utolsó feladatára. Az elhelyezkedést jelölő szűrőfeltételt az elérési útvonalban szűrni kívánt elem után kell tenni indexként, szögletes zárójelek közé `[]`. !! A sorozat első elemét a 0 jelöli. !!!! Például a `.exercises[0].result.score` lekérdezés az oldalon szereplő teszt feladatai közül az elsőnek a pontszámát kérdezi le. - A sorozatból akár több elemet, intervallumot is kiválaszthatsz a kettőspont `:` segítégével. | index | jelentés | |:------|:--------------------------------------------------------------------------------------------------------------------------| | [:3] | azokat az elemeket jelöli, amelyeknek az indexe a megjelölt értéknél kisebb, azaz a sorozat első 3 elemét | | [3:] | azokat az elemeket jelöli, amelyek indexe a megjelölt értéknél nagyobb vagy egyenlő, azaz a sorozat 4. és további elemeit | | [2:5] | egy sorozat 3-5-ig eleméig terjedő intervallumot jelöli | - A keresést a sorozat vége felől is el lehet indítani, tehát egy sorozat utolsó (utolsó előtti, utolsó három, stb.) elemét is le lehet kérdezni, ha a szögletes zárójelben negatív számot adsz meg. | index | jelentés | |:------|:-----------------------------------------------| | [-1] | egy sorozat utolsó elemét jelöli | | [-3] | egy sorozat végétől számított harmadik elemet jelöli | | [:-3] | egy sorozat utolsó 3 elemét jelöli | | [-3:] | egy sorozat utolsó 3-at megelőző elemét jelöli | - Több (nem egymás mellett elhelyezkedő) elemet is le lehet kérdezni, ha az indexeket zárójelbe `()` teszed, függőleges vonallal `|` elválasztod őket, és eléjük pontot teszel (ahogy az elérési útvonalnál). Egy sorozat első és utolsó tagját például így lehet lekérdezni: (.[0]|.[-1]). !!!! Például egy teszt első és utolsó feladatának azonosítóját így tudod lekérdezni: `.exercises(.[0] | .[-1]).id`. ### Többszörös feltételek Egy lekérdezésen belül több feltételt is meg lehet fogalmazni, amelyek egymással "és" vagy "vagy" viszonyban lehetnek. - Ha a feltételek az elérési útvonal különböző pontjaihoz illeszkednek, akkor külön feltételelemként megadhatók. Ilyenkor a feltételek "és" viszonyban lesznek egymással, tehát minden feltételnek teljesülnie kell a lekérdezéshez. !!!! A `.test{.type == "post"}.result{.scoreScaled > 60}.score` lekérdezés megadja a teszt pontszámát, ha utótesztről van szó és a teszteredmény 60%-nál jobb. - Ha a feltételelemek az elérési útvonal azonos pontjához illeszkednek (vagy valamelyik útvonal abszolútként van megfogalmazva), akkor egy kapcsoszárójelbe `{}` is írhatod őket. A két feltételt logikai operátorok válasszák el egymástól: - `&&`, ha mindkét feltételnek kell teljesülnie, - `||`, ha elegendő az egyik feltétel teljesülése! !!!! A `.test.result{.scoreScaled > 60 && ^.exercises.result.score == 0}.score` lekérdezés a tanuló tesztben elért pontszámát jeleníti meg akkor, ha a teszt százalékos eredménye jobb mint 60%, de van olyan feladat, amelyre a tanuló 0 pontot kapott. ## Függvények Függvények segítségével a lekérdezés aktuális helyén lehet különféle módosításokat és műveleteket elvégezni. A függvényeket a `#` karakter jelöli a lekérdezésen belül. Aztán jön a függvény neve, majd a `()` karakterek. A zárójelek közé megfogalmazhatunk több másik lekérdezést is vesszővel elválasztva. Ezeknek a lekérdezéseknek az eredményei az adott függvény bemenetére kerülnek. **`#min()`** A lekérdezett adatok közül a legkisebb. Például: `.exercises.result.score#min()` **`#max()`** A lekérdezett adatok közül a legnagyobb. Például: `.exercises.result.score#max()` **`#avg()`** A lekérdezett adatok átlaga. Például: `.exercises.result.score#avg()` **`#sum()`** A lekérdezett adatok összege. Például: `.exercises.result.score#sum()` **`#dateDiff()`** A függvény bal oldalán és a zárójelében szereplő lekérdezések különbsége, ha azok dátumként értelmezhetőek. Az eredménye a két időpont között eltelt idő millisec-ben számolva. Ha a zárójelet üresen hagyjuk, akkor a jelen pillanathoz képest számol különbséget. Például: `@page.result.startTime#dateDiff(@test.result.startTime)` **`#dateFormat()`** Az időbélyeget (a millisec-ben leírt időt) teszi olvashatóvá a paraméterben meghatározott formátumban. Például: `@page.result.startTime#dateDiff()#dateFormat('mm:ss')` `@page.result.startTime#dateFormat('Y. MM. DD., HH:mm:ss')` | jelölés | jelentés | példa | |---------|---------------------------------|------------------------| | `Y` | év | 2017 | | `M` | hónap sorszáma | 1, 2, ... 11, 12 | | `MM` | hónap sorszáma, mindig kétjegyű | 01, 02, ... 11, 12 | | `D` | hónap napja | 1, 2, ... 30, 31 | | `DD` | hónap napja, mindig kétjegyű | 01, 02, ... 30, 31 | | `H` | óra | 0, 1, ... 22, 23 | | `HH` | óra, mindig két jegyű | 00, 01, ... 22, 23 | | `m` | perc | 0, 1, ... 58, 59 | | `mm` | perc, mindig két jegyű | 00, 01, ... 58, 59 | | `s` | másodperc | 0, 1, ... 58, 59 | | `ss` | másodperc, mindig két jegyű | 00, 01, ... 58, 59 | !! További formázási lehetőségekért látogass el a [Moment.js][momentjsFormat] oldalára. [elérési útvonal]: #eleresi-utvonal [szűrőfeltétel]: #szurofeltetelek [állapotfa]: /lcms/reaktiv/allapotfa [szakterület-specifikus]: https://hu.wikipedia.org/wiki/Szakter%C3%BClet-specifikus_nyelv [reaktív tananyag]: /lcms/reaktiv [momentjsFormat]: https://momentjs.com/docs/#/displaying/format/