Sentry 監(jiān)控 - Snuba 數(shù)據(jù)中臺架構(SnQL 查詢語言簡介)
以下是 SnQL 的查詢結構:
- MATCH simple | join | subquery
- SELECT [expressions] | [aggregations BY expressions]
- ARRAY JOIN [column]
- WHERE condition [[AND | OR] condition]*
- HAVING condition [[AND | OR] condition]*
- ORDER BY expressions ASC|DESC [, expressions ASC|DESC]*
- LIMIT expression BY n
- LIMIT n
- OFFSET n
- GRANULARITY n
- TOTALS boolean
這些查詢作為字符串發(fā)送到 /:dataset/snql 端點,編碼為以下格式的 JSON body:
- {
- "query": "<query>",
- "dataset": "<dataset>",
- "consistent": bool,
- "turbo": bool,
- "debug": bool,
- }
數(shù)據(jù)集(dataset)通過查詢使用的 url 隱含。在 JSON 主體中,除了 query 之外的所有字段都是可選的。
MATCH
我們的數(shù)據(jù)模型由實體圖表示。該子句標識了我們正在查詢的子圖(subgraphs)的模式。目前支持三種類型的 MATCH 子句:
Simple:
- MATCH (<entity> [SAMPLE n])
這相當于我們當前的所有查詢。這是從單個實體(事件、事務等)查詢數(shù)據(jù)。可以通過將其與實體一起添加來向查詢添加可選 sample。
例如:MATCH (events)
Subquery:
- MATCH { <query> }
花括號內(nèi)可以是另一個完整的 SQL 查詢。子查詢的 SELECT/BY 子句中的任何內(nèi)容都將使用指定的別名在外部查詢中公開。
例如:
- MATCH {
- MATCH (transactions)
- SELECT avg(duration) AS avg_d BY transaction
- }
- SELECT max(avg_d)
Join(連接):
- MATCH (<alias>: <entity> [SAMPLE n]) -[<join>]-> (<alias>: <entity> [SAMPLE n])
一個 join 代表一個多節(jié)點子圖(subgraph),是一個包含不同節(jié)點之間的多個關系的子圖。目前支持節(jié)點之間的 1..n、n..1 和 1..1 有向關系。
對于 JOIN,每個實體都必須有一個別名,這是一個唯一的字符串。 抽樣(Sampling)也可以應用于 join 中的任何實體。
例如:
- MATCH
- (e: events) -[grouped]-> (g: groupedmessage),
- (e: events) -[assigned]-> (a: groupassignee)
- SELECT count() AS tot BY e.project_id, g.id
- WHERE a.user_id = "somebody"
join 類型(left/inner)和 join key 是數(shù)據(jù)模型的一部分,而不是查詢的一部分。它們被硬編碼在實體代碼中。這是因為沒有實體可以安全地與底層數(shù)據(jù)庫的分布式版本中的任何其他實體連接。
match 子句提供給 where 子句的元組(tuple)看起來與傳統(tǒng) join 子句生成的元組完全一樣:
- [
- {"e.project_id": 1, "g.id": 10}
- {"e.project_id": 1, "g.id": 11}
- {"e.project_id": 2, "g.id": 20}
- ...
- ]
SELECT .. BY
該子句指定應在輸出中返回哪些結果。如果存在聚合(aggregation),則 BY 子句中的所有內(nèi)容都被視為分組 key。如果我們想要聚合整個結果集,則可以在沒有 BY 子句的情況下進行聚合,但在這種情況下,SELECT 中只能包含聚合。即使有 BY 子句,空的 SELECT 子句也是無效的。
SELECT 子句中的表達式可以是列、算術、函數(shù)或三者的任意組合。如果查詢是 join,則每一列都必須有一個符合條件的別名,該別名與 MATCH 子句中的實體別名之一匹配。
WHERE
這是在聚合之前發(fā)生的查詢的過濾器(如 SQL 中的 WHERE)。
條件是 LHS OP RHS* 形式的中綴表達式,其中 LHS 和 RHS 是字面值或表達式。OP 指的是一個特定的運算符來比較兩個值。這些運算符是 =、!=、<、<=、>、>=、IN、NOT IN、LIKE、NOT LIKE、IS NULL、IS NOT NULL 之一。請注意,當使用像 IS NULL 這樣的運算符時,RHS 是可選的。
可以使用布爾關鍵字 AND 或 OR 組合條件。它們也可以使用 () 進行分組。
HAVING
像 WHERE 子句一樣工作,但它在 SELECT 子句中聲明的聚合之后應用。所以我們可以在這里對聚合函數(shù)的結果應用條件。
ORDER BY
指定對結果集進行排序的表達式。
LIMIT BY/LIMIT/OFFSET
不言自明,它們采用整數(shù)并在 Clickhouse 查詢中設置相應的值。如果查詢未指定 limit 或 offset,它們將分別默認為 1000 和 0。
GRANULARITY
一個整數(shù),表示對基于時間的結果進行分組的粒度。
TOTALS
如果設置為 True,來自 Snuba 的響應將有一個 “totals” key,其中包含所有選定行的總值。
SAMPLE
如果 MATCH 子句中的節(jié)點未提供采樣率,則可以在此處指定。在這種情況下,Snuba 會將 sample right 分配給查詢中的節(jié)點之一。sample 可以是介于 0 和 1 之間的浮點數(shù),表示要采樣的行的百分比。
或者它可以是一個大于 1 的整數(shù),表示要采樣的行數(shù)。