菜单
开源

UQL Parser

UQL(非结构化查询语言)是 Infinity 数据源中的一种高级查询格式,它可以整合 JSON、CSV、XML、GraphQL 格式。UQL 还提供了定制结果的能力。

UQL 是一种专门为内存操作设计的查询语言。UQL 查询可以通过一系列用 | 连接的命令构成,每行一个。大多数情况下,字段使用双引号引用,字符串值使用单引号引用。UQL 的灵感来源于 kusto 查询语言,并遵循类似的语法。

注意

UQL 仍处于测试阶段,但已被广泛使用。如果您在使用 UQL 时遇到任何问题,请在 GitHub 上提交 bug

如果您的数据看起来像这样

json
[
  {
    "id": 1,
    "name": { "firstName": "john", "lastName": "doe" },
    "dob": "1985-01-01",
    "city": "chennai"
  },
  {
    "id": 2,
    "name": { "firstName": "alice", "lastName": "bob" },
    "dob": "1990-12-31",
    "city": "london"
  }
]

那么以下 UQL 查询

sql
parse-json
| extend "full name"=strcat("name.firstName",' ',"name.lastName"), "dob"=todatetime("dob")
| project-away "name"
| order by "full name" asc

将生成一个包含四列的表格 (id, dob, city, full name)。

基本 UQL 命令

除非另有说明,所有版本都提供这些命令。

project

project 命令用于选择要在结果中包含的列。如果您想选择嵌套对象内的属性,可以使用点记法。您还可以选择为字段设置别名。

sql
parse-json
| project "id", "name.firstName", "date of birth"="dob"

project-away

project-away 命令与 project 命令完全相反。它只是从数据中删除特定的列。它不支持别名或点记法选择器。

sql
parse-json
| project-away "id", "city"

order by

order by 命令根据任何列对输入进行排序。排序方向应为 ascdesc

sql
parse-json
| order by "full name" asc

extend

extend 命令类似于 project。但它不是选择列,而是向现有数据添加/替换列。extends 需要一个别名和一个函数。

sql
parse-json
| extend "dob"=todatetime("dob"), "city"=toupper("city")

以下是一些可用函数

函数关键字语法描述可用于
trimtrim(“name”)修剪字符串0.8.0
trim_starttrim_start(“name”)移除前面的空格0.8.0
trim_endtrim_end(“name”)移除后面的空格0.8.0
tonumbertonumber(“age”)将字符串转换为数字0.8.0
tostringtostring(“age”)将数字转换为字符串0.8.0
todatetimetodatetime(“age”)将日期时间字符串转换为日期时间0.8.0
unixtime_seconds_todatetimeunixtime_seconds_todatetime(“dob”)将 Unix epoch 秒时间戳转换为日期时间0.8.0
unixtime_nanoseconds_todatetimeunixtime_nanoseconds_todatetime(“dob”)将 Unix epoch 纳秒时间戳转换为日期时间0.8.0
unixtime_milliseconds_todatetimeunixtime_milliseconds_todatetime(“dob”)将 Unix epoch 毫秒时间戳转换为日期时间0.8.0
unixtime_microseconds_todatetimeunixtime_microseconds_todatetime(“dob”)将 Unix epoch 微秒时间戳转换为日期时间0.8.0
format_datetimeformat_datetime(“dob”,‘DD/MM/YYYY’)将日期时间转换为特定格式0.8.0
add_datetimeadd_datetime(“dob”,’-1d')向日期时间字段添加持续时间0.8.0
startofminutestartofminute(“dob”)将日期时间字段四舍五入到起始分钟0.8.0
startofhourstartofhour(“dob”)将日期时间字段四舍五入到起始小时0.8.0
startofdaystartofday(“dob”)将日期时间字段四舍五入到起始天0.8.0
startofmonthstartofmonth(“dob”)将日期时间字段四舍五入到起始月0.8.0
startofweekstartofweek(“dob”)将日期时间字段四舍五入到起始周0.8.0
startofyearstartofyear(“dob”)将日期时间字段四舍五入到起始年0.8.0
extractextract(‘regex’,index,“col1”)使用 regex 和匹配索引 (0/1/..) 提取字符串字段的一部分1.0.0
sumsum(“col1”,“col2”)两个或多个列的和0.8.0
diffdiff(“col1”,“col2”)两个列的差0.8.0
mulmul(“col1”,“col2”)两个列的乘积0.8.0
divdiv(“col1”,“col2”)两个列的除法 (col1/col2)0.8.0
percentagepercentage(“col1”,“col2”)两个列的百分比 ((col1/col2)*100)1.0.0
strcatstrcat(“col1”,“col2”)连接两个或多个列0.8.0
splitsplit(“col1”,‘delimiter’)使用分隔符分割字符串1.0.0
replace_stringreplace_string(“col1”,‘src’,‘replacer’)用另一个字符串替换字符串的一部分1.0.0
reverserevers(“col1”)反转字符串1.0.0
floorfloor(“col1”)计算给定数值字段的向下取整值0.8.7
ceilceil(“col1”)计算给定数值字段的向上取整值0.8.7
roundround(“col1”)计算给定数值字段的四舍五入值0.8.7
signsign(“col1”)计算给定数值字段的符号值0.8.7
powpow(“col1”,3)计算给定数值字段的幂值0.8.7
sinsin(“col1”)计算给定数值字段的正弦值0.8.7
coscos(“col1”)计算给定数值字段的余弦值0.8.7
tantan(“col1”)计算给定数值字段的正切值0.8.7
loglog(“col1”)计算给定数值字段的对数值0.8.7
log2log2(“col1”)计算给定数值字段的 log2 值0.8.7
log10log10(“col1”)计算给定数值字段的 log10 值0.8.7
parse_urlparse_url(“col1”)将 col1 解析为 URL0.8.6
parse_url(“col1”,‘pathname’)返回 URL 的 pathname。选项包括 hosthashoriginhrefprotocolsearch0.8.6
parse_url(“col1”,‘search’,‘key1’)返回 key1 的查询字符串值。第二个参数始终为 search0.8.6
atobatob(“col1”)返回字符串列的 atob 值。参考1.3.0
btoabtoa(“col1”)返回字符串列的 btoa 值。参考1.3.0
substringsubstring(“col1”,1,5)返回字符串列的 substring 值。参考1.3.0

例如,数据 [ { "a": 12, "b" : 20 }, { "a" : 6, "b": 32} ] 和以下 uql 查询

sql
parse-json
| project "a", "triple"=sum("a","a","a"),"thrice"=mul("a",3), sum("a","b"),  diff("a","b"), mul("a","b")

将生成以下输出

a三倍三倍sumdiffmul
12363632-8240
6181838-26192

要对字段应用多个转换,请使用相同的字段名重复它们。例如,uql 查询 extend "name"=tolower("name"), "name"=trim("name") 将对 name 字段先应用 tolower 函数,然后应用 trim 函数。

还有一些其他的 extend/project 方法可用于处理数组

pack

pack 方法将键值对数组转换为 map。例如 extend "foo"=pack('key1',"value1",'key1',"value2") 将生成对象 {key1:value1,key2:value2}

array_from_entries

array_from_entries 方法从条目构建对象数组。例如 extend "foo"=array_from_entries('timestamp',[2010,2020,2030]) 将生成数组 [{timestamp:2010},{timestamp:2020},{timestamp:2030}]

array_to_map

array_to_map 将条目数组转换为 map。可以选择为键提供别名而不是索引。例如 extend "foo"=array_to_map(['chennai','india'],'city','country') 将生成 { 'city': 'chennai', 'country':'india'}

summarize

summarize 命令按字符串列聚合数据。summarize 命令需要别名、summarize 字段和 summarize 函数。以下是有效的 summarize 函数。

函数关键字语法描述可用于
countcount()值的计数0.8.0
sumsum(“age”)年龄的总和0.8.0
minmin(“population”)人口的最小值0.8.0
maxmax(“foo”)foo 的最大值0.8.0
meanmean(“foo”)foo 的平均值0.8.0

例如,以下数据

json
[
  { "city": "tokyo", "country": "japan", "population": 200 },
  { "city": "newyork", "country": "usa", "population": 60 },
  { "city": "oslo", "country": "usa", "population": 40 },
  { "city": "new delhi", "country": "india", "population": 180 },
  { "city": "mumbai", "country": "india", "population": 150 }
]

以及以下 uql 查询

sql
parse-json
| summarize "number of cities"=count(), "total population"=sum("population") by "country"
| extend "country"=toupper("country")
| order by "total population" desc

将生成如下输出表

国家城市数量总人口
INDIA2330
JAPAN1200
USA2100

pivot

pivot 是用于对数据执行透视操作的命令。pivot 命令接受 3 个参数。

  • 第一个参数是摘要。示例:count("id)sum("salary")
  • 第二个参数是行字段名。示例:"country"
  • 第三个参数是列字段名。示例:"occupation"

Pivot 示例 1

csv
name,age,country,occupation,salary
Leanne Graham,38,USA,Devops Engineer,3000
Ervin Howell,27,USA,Software Engineer,2300
Clementine Bauch,17,Canada,Student,
Patricia Lebsack,42,UK,Software Engineer,2800
Leanne Bell,38,USA,Senior Software Engineer,4000
Chelsey Dietrich,32,USA,Software Engineer,3500

以及以下查询

sql
parse-csv
| extend "salary"=tonumber("salary")
| pivot sum("salary"), "country", "occupation"

将生成

国家Devops EngineerSoftware EngineerStudentSenior Software Engineer
USA3000580004000
CANADA0000
UK0280000

而以下 summarize 查询

sql
parse-csv
| extend "salary"=tonumber("salary")
| summarize "salary"=sum("salary") by "country", "occupation"

将生成

国家occupationsalary
USADevops Engineer3000
USASoftware Engineer5800
CanadaStudent0
UKSoftware Engineer2800
UKSenior Software Engineer4000

因此,根据您的需要选择 summarizepivot

parse-json

parse-json 命令用于指示 UQL 将响应解析为 JSON

parse-csv

parse-csv 命令用于指示 UQL 将响应解析为 CSV

parse-xml

parse-xml 命令用于指示 UQL 将响应解析为 XML

parse-yaml

parse-yaml 用于指定结果为 YAML 格式

count

count

sql
parse-json
| count

count 提供结果的数量。

limit

sql
parse-json
| limit 10

limit 命令限制返回结果的数量。例如,以下查询只返回 10 个结果

scope

scope 命令设置输出数据的上下文。当结果位于嵌套的 json 对象内部时很有用。

json
{
  "meta": { "last-updated": "2021-08-09" },
  "count": 2,
  "users": [{ "name": "foo" }, { "name": "bar" }]
}

示例

sql
parse-json
| scope "users"

以下 uql 查询仅返回“users”并忽略其他根级别属性。

mv-expand

json
[
  { "group": "A", "users": ["user a1", "user a2"] },
  { "group": "B", "users": ["user b1"] }
]

mv-expand 将多值属性扩展为独立的记录。例如,对以下数据使用命令 mv-expand "user"="users"

json
[
  { "group": "A", "user": "user a1" },
  { "group": "A", "user": "user a2" },
  { "group": "B", "user": "user b1" }
]

将生成如下结果

mv-expand 也应适用于非字符串数组。

project kv()

project kv() 命令用于将给定的对象转换为键值对。

示例:对于数据 { "a": {"name":"a1"}, "b": {"name":"b1"}, "c": {"name":"c1"} } 和查询 parse-json | project kv() 将生成以下表格
a
{"name":"a1"}b
{"name":"b1"}c

{"name":"c1"}

此命令也可与参数一起使用

示例:对于数据 { "data": { "a": {"name":"a1"}, "b": {"name":"b1"}, "c": {"name":"c1"} } } 和查询 parse-json | project kv("data") 将生成相同的结果

project kv() 命令仅在插件 0.8.7 及以上版本中可用

JSONata

sql
parse-json
| scope "library"
| jsonata "library.loans@$L.books@$B[$L.isbn=$B.isbn].customers[$L.customer=id].{ 'customer': name, 'book': $B.title, 'due': $L.return}"
| count

jsonata 命令接受一个 JSONata 查询并应用于先前的输入

像任何其他命令一样,jsonata 命令可以与多个命令组合/通过管道连接。您也可以使用 JSONata 进行数据过滤。

从 0.8.8 版本开始支持 JSONata

注释