Psaní dotazů pro Azure Data Explorer
V tomto článku se dozvíte, jak používat dotazovací jazyk v Azure Průzkumník dat k provádění základních dotazů s nejběžnějšími operátory. Také se dostanete k některým pokročilejším funkcím tohoto jazyka.
Požadavky
- Předplatné Azure. Vytvořte si bezplatný účet Azure.
- Vytvořte cluster a databázi.
Dotazy v tomto článku můžete spustit jedním ze dvou způsobů:
V clusteru Azure Průzkumník dat pomoci , který jsme nastavili na podporu učení. Přihlaste se ke clusteru pomocí e-mailového účtu organizace, který je členem Azure Active Directory.
Ve vlastním clusteru, který obsahuje ukázková data StormEvents. Další informace najdete v tématu rychlý Start: Vytvoření clusteru azure Průzkumník dat a databáze a ingestování ukázkových dat do Azure Průzkumník dat.
Ukázková datová sada StormEvents obsahuje data týkající se počasí od National Centers for Environmental Information.
Přehled dotazovacího jazyka
Dotaz v Azure Průzkumník dat je žádost jen pro čtení ke zpracování dat a vrácení výsledků. Požadavky se uvádí v prostém textu s využitím modelu toku dat, který je navržený pro snadné čtení, vytváření a automatizaci syntaxe. dotaz používá entity schématu, které jsou uspořádány v hierarchii podobně jako SQL: databáze, tabulky a sloupce.
Dotaz se skládá z sekvence příkazů dotazu, oddělený středníkem ( ; ), s alespoň jedním příkazem, který je tabulkovým výrazem, který je příkaz, který vytváří data uspořádaná do mřížky jako tabulka sloupců a řádků. Příkazy tabulkových výrazů dotazu generují výsledky dotazu.
Syntaxe příkazu tabulkového výrazu má tabulkový tok dat z jednoho operátoru dotazu na jiný, počínaje zdrojem dat (například tabulka v databázi nebo operátor, který vytváří data) a následně přetéká sadou operátorů transformace dat, které jsou vázány pomocí | oddělovače kanálu ().
Například následující dotaz má jediný příkaz, který je tabulkový výraz příkazu. Příkaz začíná odkazem na tabulku StormEvents (databáze hostující tuto tabulku tady není explicitně uvedená a je součástí informací o připojení). Data (řádky) této tabulky se potom filtrují podle hodnoty sloupce StartTime a pak podle hodnoty sloupce State. Dotaz pak vrátí počet zbývajících řádků.
StormEvents
| where StartTime >= datetime(2007-11-01) and StartTime < datetime(2007-12-01)
| where State == "FLORIDA"
| count
V tomto případě je výsledkem:
| Počet |
|---|
| 23 |
Další informace najdete v referenčních informacích k dotazovacímu jazyku.
Nejběžnější operátory
Operátory uvedené v této části jsou stavebními bloky pro porozumění dotazům v Azure Průzkumník dat. Většina dotazů, které zapisujete, bude obsahovat několik z těchto operátorů.
Spuštění dotazů v clusteru Help: vyberte Kliknutím spustíte dotaz nad každým dotazem.
Spuštění dotazů na vlastním clusteru:
Zkopírujte každý dotaz do webové aplikace dotazů a pak buď vyberte dotaz, nebo umístěte kurzor do dotazu.
V horní části aplikace vyberte Spustit.
count
Count: vrátí počet řádků v tabulce.
Následující dotaz vrátí počet řádků v tabulce StormEvents.
StormEvents | count
take
přijmout: vrátí až zadaný počet řádků dat.
Následující dotaz vrátí pět řádků z tabulky StormEvents. Omezení klíčového slova je alias pro přijetí.
StormEvents | take 5
Tip
Není nijak zaručeno, které záznamy se vrátí, pokud zdrojová data nejsou seřazená.
projekt
projekt: vybere podmnožinu sloupců.
Následující dotaz vrátí konkrétní sadu sloupců.
StormEvents
| take 5
| project StartTime, EndTime, State, EventType, DamageProperty, EpisodeNarrative
kde:
kde: filtruje tabulku na podmnožinu řádků, které odpovídají predikátu.
Následující dotaz filtruje data podle EventType a State .
StormEvents
| where EventType == 'Flood' and State == 'WASHINGTON'
| take 5
| project StartTime, EndTime, State, EventType, DamageProperty, EpisodeNarrative
sort
Sort: seřadit řádky vstupní tabulky do pořadí podle jednoho nebo více sloupců.
Následující dotaz seřadí data v sestupném pořadí podle DamageProperty .
StormEvents
| where EventType == 'Flood' and State == 'WASHINGTON'
| sort by DamageProperty desc
| take 5
| project StartTime, EndTime, State, EventType, DamageProperty, EpisodeNarrative
Poznámka
Pořadí operací je důležité. Zkuste vložit take 5 před sort by . Získáte různé výsledky?
top
Top: vrátí prvních N záznamů seřazených podle zadaných sloupců.
Následující dotaz vrátí stejné výsledky jako u jednoho operátoru s menším množstvím.
StormEvents
| where EventType == 'Flood' and State == 'WASHINGTON'
| top 5 by DamageProperty desc
| project StartTime, EndTime, State, EventType, DamageProperty, EpisodeNarrative
zvětšení
Extended: COMPUTE odvozené sloupce.
Následující dotaz vytvoří nový sloupec pomocí výpočtu hodnoty v každém řádku.
StormEvents
| where EventType == 'Flood' and State == 'WASHINGTON'
| top 5 by DamageProperty desc
| extend Duration = EndTime - StartTime
| project StartTime, EndTime, Duration, State, EventType, DamageProperty, EpisodeNarrative
Výrazy mohou zahrnovat všechny obvyklé operátory (+,-, *,/,%) a existuje rozsah užitečných funkcí, které můžete volat.
Souhrn
Shrnutí: agreguje skupiny řádků.
Následující dotaz vrátí počet událostí podle State .
StormEvents
| summarize event_count = count() by State
Operátor sumarizace seskupí řádky, které mají stejné hodnoty v klauzuli podle , a pak pomocí agregační funkce (například Count) kombinuje každou skupinu do jednoho řádku. V tomto případě je v tomto případě řádek pro každý stav a sloupec pro počet řádků v tomto stavu.
Existuje řada agregačních funkcí a můžete použít několik z nich v jednom operátoru Shrnutí k vytvoření několika počítaných sloupců. Můžete například získat počet nekonzistencí v jednotlivých stavech a jedinečné množství nekonzistencí pro každý stav a potom použít horní seznam a získat tak nejvíc ovlivněných stavů.
StormEvents
| summarize StormCount = count(), TypeOfStorms = dcount(EventType) by State
| top 5 by StormCount desc
Výsledkem operace sumarizace je:
Každý sloupec s názvem v
Sloupec pro každý počítaný výraz
Řádek pro každou kombinaci podle hodnot
činit
Render: vykreslí výsledky jako grafický výstup.
Následující dotaz zobrazí sloupcový graf.
StormEvents
| summarize event_count=count(), mid = avg(BeginLat) by State
| sort by mid
| where event_count > 1800
| project State, event_count
| render columnchart
Následující dotaz zobrazí jednoduchý časový graf.
StormEvents
| summarize event_count=count() by bin(StartTime, 1d)
| render timechart
Následující dotaz počítá události podle času modulo za jeden den, rozdělený v hodinách a zobrazuje graf času.
StormEvents
| extend hour = floor(StartTime % 1d , 1h)
| summarize event_count=count() by hour
| sort by hour asc
| render timechart
Následující dotaz porovnává více denních řad v časovém grafu.
StormEvents
| extend hour= floor( StartTime % 1d , 1h)
| where State in ("GULF OF MEXICO","MAINE","VIRGINIA","WISCONSIN","NORTH DAKOTA","NEW JERSEY","OREGON")
| summarize event_count=count() by hour, State
| render timechart
Poznámka
Operátor vykreslování je funkce na straně klienta, nikoli součást modulu. Je integrována do jazyka pro snadné použití. Webová aplikace podporuje následující možnosti: barchart, columnchart, piechart, timechart a linechart.
Skalární operátory
Tato část popisuje některé z nejdůležitějších skalárních operátorů.
bin()
bin(): Zaokrouhlí hodnoty dolů na celé číslo násobek dané velikosti přihrádky.
Následující dotaz vypočítá počet s velikostí kbelíku jeden den.
StormEvents
| where StartTime > datetime(2007-02-14) and StartTime < datetime(2007-02-21)
| summarize event_count = count() by bin(StartTime, 1d)
case()
case(): Vyhodnotí seznam predikátů a vrátí první výsledný výraz, jehož predikát je splněn, nebo konečný výraz else. Pomocí tohoto operátoru můžete data kategorizovat nebo seskupit:
Následující dotaz vrátí nový sloupec a deaths_bucket seskupí úmrtí podle čísla.
StormEvents
| summarize deaths = sum(DeathsDirect) by State
| extend deaths_bucket = case (
deaths > 50, "large",
deaths > 10, "medium",
deaths > 0, "small",
"N/A")
| sort by State asc
extract()
extract(): Získá shodu regulárního výrazu z textového řetězce.
Následující dotaz extrahuje hodnoty konkrétních atributů z trasování.
let MyData = datatable (Trace: string) ["A=1, B=2, Duration=123.45,...", "A=1, B=5, Duration=55.256, ..."];
MyData
| extend Duration = extract("Duration=([0-9.]+)", 1, Trace, typeof(real)) * time(1s)
Tento dotaz používá příkaz let, který vytvoří vazbu názvu (v tomto případě ) na výraz. Pro zbytek oboru, ve kterém se zobrazí příkaz let (globální rozsah nebo v rozsahu těla funkce), lze název použít k odkazování na jeho vázaný hodnotu.
parse_json()
parse_json():Interpretuje řetězec jako hodnotu JSON a vrátí hodnotu jako dynamickou. Je lepší použít funkci extractjson(), když potřebujete extrahovat více než jeden prvek složeného objektu JSON.
Následující dotaz extrahuje prvky JSON z pole.
let MyData = datatable (Trace: string)
['{"duration":[{"value":118.0,"valcount":5.0,"min":100.0,"max":150.0,"stdDev":0.0}]}'];
MyData
| extend NewCol = parse_json(Trace)
| project NewCol.duration[0].value, NewCol.duration[0].valcount, NewCol.duration[0].min, NewCol.duration[0].max, NewCol.duration[0].stdDev
Následující dotaz extrahuje elementy JSON.
let MyData = datatable (Trace: string) ['{"value":118.0,"valcount":5.0,"min":100.0,"max":150.0,"stdDev":0.0}'];
MyData
| extend NewCol = parse_json(Trace)
| project NewCol.value, NewCol.valcount, NewCol.min, NewCol.max, NewCol.stdDev
Následující dotaz extrahuje elementy JSON s dynamickým datovým typem.
let MyData = datatable (Trace: dynamic)
[dynamic({"value":118.0,"counter":5.0,"min":100.0,"max":150.0,"stdDev":0.0})];
MyData
| project Trace.value, Trace.counter, Trace.min, Trace.max, Trace.stdDev
ago()
ago(): Odečte daný časový interval od aktuálního času času UTC.
Následující dotaz vrátí data za posledních 12 hodin.
//The first two lines generate sample data, and the last line uses
//the ago() operator to get records for last 12 hours.
print TimeStamp= range(now(-5d), now(), 1h), SomeCounter = range(1,121)
| mv-expand TimeStamp, SomeCounter
| where TimeStamp > ago(12h)
startofweek()
startofweek(): Vrátí začátek týdne obsahující datum posunuté o posun, pokud je k dispozici.
Následující dotaz vrátí začátek týdne s různými posuny.
range offset from -1 to 1 step 1
| project weekStart = startofweek(now(), offset),offset
Tento dotaz používá operátor rozsahu, který generuje tabulku hodnot s jedním sloupcem. Viz také: startofday(), startofweek(), startofyear()), startofmonth(), endofday(), endofweek(), endofmonth()a endofyear().
between()
between(): Odpovídá vstupu, který je uvnitř inkluzivního rozsahu.
Následující dotaz filtruje data podle daného rozsahu dat.
StormEvents
| where StartTime between (datetime(2007-07-27) .. datetime(2007-07-30))
| count
Následující dotaz filtruje data podle daného rozsahu dat s mírnou odchylkou tří dnů ( 3d ) od počátečního data.
StormEvents
| where StartTime between (datetime(2007-07-27) .. 3d)
| count
Tabulkové operátory
Kusto má mnoho tabelárních operátorů, z nichž některé jsou uvedené v dalších částech tohoto článku. Tady se zaměříme na parsovat.
parse
parse: Vyhodnotí řetězcový výraz a parsuje jeho hodnotu do jednoho nebo více počítaných sloupců. Existují tři způsoby, jak parsovat: jednoduché (výchozí), regulární výrazy a uvolněné.
Následující dotaz analyzuje trasování a extrahuje relevantní hodnoty pomocí výchozí jednoduché analýzy. Výraz (označované jako StringConstant) je hodnota běžného řetězce a shoda je striktní: rozšířené sloupce musí odpovídat požadovaným typům.
let MyTrace = datatable (EventTrace:string)
[
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=23, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=15, lockTime=02/17/2016 08:40:00Z, releaseTime=02/17/2016 08:40:00Z, previousLockTime=02/17/2016 08:39:00Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=20, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=22, lockTime=02/17/2016 08:41:01Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=16, lockTime=02/17/2016 08:41:00Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:00Z)'
];
MyTrace
| parse EventTrace with * "resourceName=" resourceName ", totalSlices=" totalSlices:long * "sliceNumber=" sliceNumber:long * "lockTime=" lockTime ", releaseTime=" releaseTime:date "," * "previousLockTime=" previouLockTime:date ")" *
| project resourceName ,totalSlices , sliceNumber , lockTime , releaseTime , previouLockTime
Následující dotaz analyzuje trasování a extrahuje relevantní hodnoty pomocí kind = regex . StringConstant může být regulární výraz.
let MyTrace = datatable (EventTrace:string)
[
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=23, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=15, lockTime=02/17/2016 08:40:00Z, releaseTime=02/17/2016 08:40:00Z, previousLockTime=02/17/2016 08:39:00Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=20, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=22, lockTime=02/17/2016 08:41:01Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=16, lockTime=02/17/2016 08:41:00Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:00Z)'
];
MyTrace
| parse kind = regex EventTrace with "(.*?)[a-zA-Z]*=" resourceName @", totalSlices=\s*\d+\s*.*?sliceNumber=" sliceNumber:long ".*?(previous)?lockTime=" lockTime ".*?releaseTime=" releaseTime ".*?previousLockTime=" previousLockTime:date "\\)"
| project resourceName , sliceNumber , lockTime , releaseTime , previousLockTime
Následující dotaz analyzuje trasování a extrahuje relevantní hodnoty pomocí kind = relaxed . StringConstant je normální řetězcová hodnota a shoda je uvolněná: rozšířené sloupce mohou částečně odpovídat požadovaným typům.
let MyTrace = datatable (EventTrace:string)
[
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=23, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=15, lockTime=02/17/2016 08:40:00Z, releaseTime=02/17/2016 08:40:00Z, previousLockTime=02/17/2016 08:39:00Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=20, lockTime=02/17/2016 08:40:01Z, releaseTime=02/17/2016 08:40:01Z, previousLockTime=02/17/2016 08:39:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=22, lockTime=02/17/2016 08:41:01Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:01Z)',
'Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=27, sliceNumber=16, lockTime=02/17/2016 08:41:00Z, releaseTime=02/17/2016 08:41:00Z, previousLockTime=02/17/2016 08:40:00Z)'
];
MyTrace
| parse kind=relaxed "Event: NotifySliceRelease (resourceName=PipelineScheduler, totalSlices=NULL, sliceNumber=23, lockTime=02/17/2016 08:40:01, releaseTime=NULL, previousLockTime=02/17/2016 08:39:01)" with * "resourceName=" resourceName ", totalSlices=" totalSlices:long * "sliceNumber=" sliceNumber:long * "lockTime=" lockTime ", releaseTime=" releaseTime:date "," * "previousLockTime=" previousLockTime:date ")" *
| project resourceName ,totalSlices , sliceNumber , lockTime , releaseTime , previousLockTime
Analýza časových řad
řada make-series
make-series:Agreguje skupiny řádků, jako je sumarizovat, ale vygeneruje (time) vektor řady pro každou kombinaci hodnot.
Následující dotaz vrátí sadu časových řad pro počet událostí storm za den. Dotaz pokrývá tříměsíční období pro každý stav a vyplňuje chybějící přihrádky konstantou 0:
StormEvents
| make-series n=count() default=0 on StartTime in range(datetime(2007-01-01), datetime(2007-03-31), 1d) by State
Jakmile vytvoříte sadu (časových) řad, můžete pomocí funkcí řad detekovat neobvyklé tvary, sezónní vzory a mnoho dalšího.
Následující dotaz extrahuje první tři stavy, které měly nejvíce událostí v konkrétní den:
StormEvents
| make-series n=count() default=0 on StartTime in range(datetime(2007-01-01), datetime(2007-03-31), 1d) by State
| extend series_stats(n)
| top 3 by series_stats_n_max desc
| render timechart
Další informace najdete v úplném seznamu funkcí řady.
Pokročilé agregace
Základní agregace, jako je počet a souhrn, jsme prokrylidříve v tomto článku. Tato část představuje pokročilejší možnosti.
top-nested
top-nested:Vytváří hierarchické nejvyšší výsledky, kde každá úroveň je přechod k podrobnostem založeným na hodnotách předchozí úrovně.
Tento operátor je užitečný pro scénáře vizualizace řídicího panelu nebo v případě, že je potřeba odpovědět na otázku, jako je tato: "Vyhledání horních N hodnot K1 (pomocí nějaké agregace); pro každý z nich zjistěte, jaké jsou nejvyšší hodnoty M K2 (pomocí jiné agregace); ..."
Následující dotaz vrátí hierarchickou tabulku s parametrem na State nejvyšší úrovni, za kterou následuje Sources .
StormEvents
| top-nested 2 of State by sum(BeginLat),
top-nested 3 of Source by sum(BeginLat),
top-nested 1 of EndLocation by sum(BeginLat)
Modul plug-in pivot()
Modul plug-in pivot():Otočí tabulku tak, že jedinečné hodnoty z jednoho sloupce ve vstupní tabulce přemění na několik sloupců ve výstupní tabulce. Operátor provádí agregace, kde jsou vyžadovány u všech zbývajících hodnot sloupců v konečném výstupu.
Následující dotaz použije filtr a přehodí řádky do sloupců.
StormEvents
| project State, EventType
| where State startswith "AL"
| where EventType has "Wind"
| evaluate pivot(State)
dcount()
dcount(): Vrátí odhad počtu jedinečných hodnot výrazu ve skupině. Ke spočítání všech hodnot použijte count().
Následující dotaz spočítá distinct Source podle State .
StormEvents
| summarize Sources = dcount(Source) by State
dcountif()
dcountif(): Vrátí odhad počtu jedinečných hodnot výrazu pro řádky, pro které se predikát vyhodnotí jako true.
Následující dotaz spočítá odlišné hodnoty Source , kde DamageProperty < 5000 .
StormEvents
| take 100
| summarize Sources = dcountif(Source, DamageProperty < 5000) by State
dcount_hll()
dcount_hll():Vypočítá dcount z výsledků HyperLogLog (generovaných pomocí hllnebo hll_merge.
Následující dotaz k vygenerování počtu používá algoritmus HLL.
StormEvents
| summarize hllRes = hll(DamageProperty) by bin(StartTime,10m)
| summarize hllMerged = hll_merge(hllRes)
| project dcount_hll(hllMerged)
arg_max()
arg_max():Najde řádek ve skupině, který maximalizuje výraz, a vrátí hodnotu jiného výrazu (nebo * pro vrácení celého řádku).
Následující dotaz vrátí čas poslední sestavy zahlcení v každém stavu.
StormEvents
| where EventType == "Flood"
| summarize arg_max(StartTime, *) by State
| project State, StartTime, EndTime, EventType
makeset()
makeset(): Vrátí dynamické pole (JSON) sady jedinečných hodnot, které výraz přebírá ve skupině.
Následující dotaz vrátí všechny časy, kdy byl v jednotlivých stavech nahlášen čas, a vytvoří pole ze sady různých hodnot.
StormEvents
| where EventType == "Flood"
| summarize FloodReports = makeset(StartTime) by State
| project State, FloodReports
MV – rozbalit
MV-expand: rozbalí kolekce s více hodnotami z dynamického typu sloupce tak, aby každá hodnota v kolekci měla samostatný řádek. Všechny ostatní sloupce v rozbaleném řádku jsou duplicitní. Je opakem z MakeList.
Následující dotaz generuje ukázková data vytvořením sady a jejím použitím k předvedení možností rozšíření MV .
let FloodDataSet = StormEvents
| where EventType == "Flood"
| summarize FloodReports = makeset(StartTime) by State
| project State, FloodReports;
FloodDataSet
| mv-expand FloodReports
percentiles()
percentily (): Vrátí odhad pro zadaný percentil s nejbližším pořadím populace, která je definována výrazem. Přesnost závisí na hustotě populace v oblasti percentilu. Dá se použít jenom v kontextu agregace v rámci sumarizace.
Následující dotaz vypočítá percentily pro dobu trvání.
StormEvents
| extend duration = EndTime - StartTime
| where duration > 0s
| where duration < 3h
| summarize percentiles(duration, 5, 20, 50, 80, 95)
Následující dotaz vypočítá percentily pro dobu trvání hodnoty násobené stavem a normalizuje data o pět minut přihrádek ( 5m ).
StormEvents
| extend duration = EndTime - StartTime
| where duration > 0s
| where duration < 3h
| summarize event_count = count() by bin(duration, 5m), State
| summarize percentiles(duration, 5, 20, 50, 80, 95) by State
Vzájemná datová sada
Tato část se zabývá prvky, které vám umožní vytvářet složitější dotazy, spojovat data napříč tabulkami a dotazovat se napříč databázemi a clustery.
aplikaci
let: vylepšuje modularitu a opakované použití. Příkaz let umožňuje rozdělit potenciálně složitý výraz na více částí, z nichž každá je svázána s názvem, a vytvořit tyto části dohromady. Příkaz let lze použít také k vytvoření uživatelem definovaných funkcí a zobrazení (výrazy nad tabulkami, jejichž výsledky vypadají jako nová tabulka). Výrazy vázané pomocí příkazu let mohou být skalárního typu, tabulkového typu nebo uživatelsky definované funkce (výrazy lambda).
Následující příklad vytvoří proměnnou tabelárního typu a použije ji v následném výrazu.
let LightningStorms =
StormEvents
| where EventType == "Lightning";
let AvalancheStorms =
StormEvents
| where EventType == "Avalanche";
LightningStorms
| join (AvalancheStorms) on State
| distinct State
join
Join: sloučí řádky dvou tabulek a vytvoří novou tabulku tak, že bude odpovídat hodnotám zadaného sloupce z každé tabulky. Kusto podporuje celou škálu typů spojení: FullOuter, Inner, innerunique, leftanti, leftantisemi, LeftOuter, leftsemi, rightanti, rightantisemi, RightOuter, rightsemi.
Následující příklad spojí dvě tabulky s vnitřním spojením.
let X = datatable(Key:string, Value1:long)
[
'a',1,
'b',2,
'b',3,
'c',4
];
let Y = datatable(Key:string, Value2:long)
[
'b',10,
'c',20,
'c',30,
'd',40
];
X
| join kind=inner Y on Key
Tip
Pomocí operátorů WHERE a projektu můžete snížit počet řádků a sloupců ve vstupních tabulkách před připojením. Je-li jedna tabulka vždy menší než druhá, použijte ji jako levou (v kanálu) na straně spojení. Sloupce pro shodu spojení musí mít stejný název. Použijte operátor projektu , pokud je to nutné k přejmenování sloupce v jedné z tabulek.
serializovat
serializace: serializace sady řádků, aby bylo možné používat funkce, které vyžadují Serializovaná data, například ROW_NUMBER ().
Následující dotaz je úspěšný, protože data jsou serializována.
StormEvents
| summarize count() by State
| serialize
| extend row_number = row_number()
Sada řádků je také považována za serializovanou, pokud je výsledkem operátorů řazení, horníchnebo rozsahů , volitelně následovaných projektem, projektem, rozšiřuje, WHERE, analyze, MV-expandnebo přebírají operátory.
StormEvents
| summarize count() by State
| sort by State asc
| extend row_number = row_number()
Dotazy napříč databázemi a clustery
Dotazy mezi databázemi a meziclustery: můžete zadat dotaz na databázi ve stejném clusteru tak, že na ni odkazujete jako na . Dotaz na databázi na vzdáleném clusteru můžete vytvořit tak, že na ni odkazujete jako na cluster("MyCluster").database("MyDatabase").MyTable .
Následující dotaz se volá z jednoho clusteru a dotazuje se na data z MyCluster clusteru. Chcete-li spustit tento dotaz, použijte vlastní název clusteru a název databáze.
cluster("MyCluster").database("Wiki").PageViews
| where Views < 2000
| take 1000;
Analýza uživatelů
Tato část obsahuje prvky a dotazy, které ukazují, jak snadné je provádět analýzu chování uživatele v Kusto.
Modul plug-in activity_counts_metrics
modul plug-in activity_counts_metrics: vypočítá užitečnou metriku aktivity (celkový počet hodnot, jedinečný počet hodnot, jedinečný počet nových hodnot a agregovaný jedinečný počet). Metriky se vypočtou pro každé časové okno, pak se porovnávají a agreguje do a s využitím všech předchozích časových oken.
Následující dotaz analyzuje přijetí uživatelem pomocí výpočtu denních počtů aktivit.
let start=datetime(2017-08-01);
let end=datetime(2017-08-04);
let window=1d;
let T = datatable(UserId:string, Timestamp:datetime)
[
'A', datetime(2017-08-01),
'D', datetime(2017-08-01),
'J', datetime(2017-08-01),
'B', datetime(2017-08-01),
'C', datetime(2017-08-02),
'T', datetime(2017-08-02),
'J', datetime(2017-08-02),
'H', datetime(2017-08-03),
'T', datetime(2017-08-03),
'T', datetime(2017-08-03),
'J', datetime(2017-08-03),
'B', datetime(2017-08-03),
'S', datetime(2017-08-03),
'S', datetime(2017-08-04),
];
T
| evaluate activity_counts_metrics(UserId, Timestamp, start, end,
window)
Modul plug-in activity_engagement
modul plug-in activity_engagement: vypočítá poměr zapojení aktivity na základě sloupce ID přes posuvné okno časové osy. modul plug-in activity_engagement lze použít pro výpočet Dau, WAU a MAU (denně, týdně a měsíčně aktivních uživatelů).
Následující dotaz vrátí poměr celkových jedinečných uživatelů, kteří používají aplikaci denně v porovnání s celkovým počtem jedinečných uživatelů, kteří používají aplikaci týdně, na přesunu sedmi dnů.
// Generate random data of user activities
let _start = datetime(2017-01-01);
let _end = datetime(2017-01-31);
range _day from _start to _end step 1d
| extend d = tolong((_day - _start)/1d)
| extend r = rand()+1
| extend _users=range(tolong(d*50*r), tolong(d*50*r+100*r-1), 1)
| mv-expand id=_users to typeof(long) limit 1000000
// Calculate DAU/WAU ratio
| evaluate activity_engagement(['id'], _day, _start, _end, 1d, 7d)
| project _day, Dau_Wau=activity_ratio*100
| render timechart
Tip
Při výpočtu DAU/MAU změňte koncová data a období přesunutí (OuterActivityWindow).
Modul plug-in activity_metrics
modul plug-in activity_metrics: vypočítá užitečnou metriku aktivity (jedinečné hodnoty počtu, jedinečný počet nových hodnot, míru uchování a míru četnosti změn) na základě okna aktuální období vs. předchozího období.
Následující dotaz vypočítá četnost a míru uchování pro danou datovou sadu.
// Generate random data of user activities
let _start = datetime(2017-01-02);
let _end = datetime(2017-05-31);
range _day from _start to _end step 1d
| extend d = tolong((_day - _start)/1d)
| extend r = rand()+1
| extend _users=range(tolong(d*50*r), tolong(d*50*r+200*r-1), 1)
| mv-expand id=_users to typeof(long) limit 1000000
| where _day > datetime(2017-01-02)
| project _day, id
// Calculate weekly retention rate
| evaluate activity_metrics(['id'], _day, _start, _end, 7d)
| project _day, retention_rate*100, churn_rate*100
| render timechart
Modul plug-in new_activity_metrics
modul plug-in new_activity_metrics: vypočítá užitečnou metriku aktivity (jedinečný počet hodnot, jedinečný počet nových hodnot, míru uchování a míru četnosti změn) pro kohorta nových uživatelů. Koncept tohoto modulu plug-in je podobný jako modul plug-in activity_metrics, ale zaměřuje se na nové uživatele.
Následující dotaz vypočítá míru uchování a četnosti změn pomocí okna týden po týdnu pro nové uživatele kohorta (uživatelé, kteří dorazili první týden).
// Generate random data of user activities
let _start = datetime(2017-05-01);
let _end = datetime(2017-05-31);
range Day from _start to _end step 1d
| extend d = tolong((Day - _start)/1d)
| extend r = rand()+1
| extend _users=range(tolong(d*50*r), tolong(d*50*r+200*r-1), 1)
| mv-expand id=_users to typeof(long) limit 1000000
// Take only the first week cohort (last parameter)
| evaluate new_activity_metrics(['id'], Day, _start, _end, 7d, _start)
| project from_Day, to_Day, retention_rate, churn_rate
Modul plug-in session_count
modul plug-in session_count: vypočítá počet relací na základě sloupce ID na časové ose.
Následující dotaz vrátí počet relací. Relace se považuje za aktivní, pokud se ID uživatele zobrazí alespoň jednou v časovém intervalu 100. v časovém intervalu po dobu až je to 41 časů.
let _data = range Timeline from 1 to 9999 step 1
| extend __key = 1
| join kind=inner (range Id from 1 to 50 step 1 | extend __key=1) on __key
| where Timeline % Id == 0
| project Timeline, Id;
// End of data definition
_data
| evaluate session_count(Id, Timeline, 1, 10000, 100, 41)
| render linechart
Modul plug-in funnel_sequence
modul plug-in funnel_sequence: vypočítá jedinečný počet uživatelů, kteří provedli sekvenci stavů. ukazuje rozdělení předchozích a dalších stavů, které vedla nebo byly následovány sekvencí.
Následující dotaz ukazuje, co událost nastane před a po všech Tornado událostech v 2007.
// Looking on StormEvents statistics:
// Q1: What happens before Tornado event?
// Q2: What happens after Tornado event?
StormEvents
| evaluate funnel_sequence(EpisodeId, StartTime, datetime(2007-01-01), datetime(2008-01-01), 1d,365d, EventType, dynamic(['Tornado']))
Modul plug-in funnel_sequence_completion
modul plug-in funnel_sequence_completion: vypočítá trychtýři dokončených kroků sekvence v různých časových obdobích.
Následující dotaz zkontroluje trychtýři dokončení sekvence: Hail -> Tornado -> Thunderstorm -> Wind v celkovém počtu hodin jedné hodiny, čtyři hodiny a jeden den ( [1h, 4h, 1d] ).
let _start = datetime(2007-01-01);
let _end = datetime(2008-01-01);
let _windowSize = 365d;
let _sequence = dynamic(['Hail', 'Tornado', 'Thunderstorm', 'Wind']);
let _periods = dynamic([1h, 4h, 1d]);
StormEvents
| evaluate funnel_sequence_completion(EpisodeId, StartTime, _start, _end, _windowSize, EventType, _sequence, _periods)
Functions
Tato část se zabývá funkcemi: opakovaně použitelnými dotazy uloženými na serveru. Funkce mohou být vyvolány dotazy a jinými funkcemi (rekurzivní funkce nejsou podporovány).
Poznámka
Nemůžete vytvořit funkce v clusteru Help, který je jen pro čtení. Pro tuto část použijte vlastní testovací cluster.
Následující příklad vytvoří funkci, která jako argument přijímá název stavu ( MyState ).
.create function with (folder="Demo")
MyFunction (MyState: string)
{
StormEvents
| where State =~ MyState
}
Následující příklad volá funkci, která získává data pro stav Texas.
MyFunction ("Texas")
| summarize count()
Následující příklad odstraní funkci, která byla vytvořena v prvním kroku.
.drop function MyFunction