flux语言

flux语言是influxdb2.0以上才支持的语言,influxdb1.8版本做了向后兼容,因此也可以使用flux语言。

在此之前influxdb的查询语言是influxQL,influx到了2.0版本之后又推出了apl,允许使用influxQL进行查询。

由官方文档Flux versions in InfluxDB | Flux 0.x Documentation,得知不同的influxdb版本支持的flux语言不同:

flux语法

变量与基本表达式: 

这样点击submit会报错,想要正常运行,就要把数字放在表里面。

解决方法:使用array.from函数解决这个问题:

点击inject:

谓词表达式:

(点击submit会默认提交query里面的结果)

大小比较:

字符串大小比较:按照utf-8的编码,对英文有效(先比第一个,在比第二个...),对中文无效。

数字比较:可以跨类型比较。

特殊情况:

结果是false,因为0.1在计算机底层可能是0.100000000001.索引大于0.3

且和或:

and,or

正则表达式:

不会

逻辑取反:

not

控制语句:

只保留了三元运算符

三元运算符:

import "array"

x = 2
a = if x==0 then "green" else if x==1 then "red" else "yellow"

array.from(rows: [{"value":a}])

10种基本数据类型(具体看文档)

bool:

import "array"

x = 0
b = bool(v: x)

array.from(rows: [{"value":b}])

x的值只能是0或1,可以是浮点数,也可以是字符串的“1”或“true”。 

bytes:

注意是 bytes(复数)不是 byte,bytes 类型表示一个由字节组成的序列。无法直接声明一个字节序列,只能转成字节序列。

代码这样写时,会报错:

import "array"

b = "abc"
x = bytes(v: b)

array.from(rows: [{"value":x}])

因为flux数据要放到表里面,即数据要有行有列,有列即有类型,而flux支持bytes,influxdb不支持bytes。

解决方法:

1.把bytes类型转换成字符串:

import "array"

b = "abc"
x = bytes(v: b)
c = string(v: x)

array.from(rows: [{"value":c}])

 2.display函数打印字节序列

import "array"

b = "abc"
x = bytes(v: b)
c = display(v: x)

array.from(rows: [{"value":c}])

返回utf-8编码之后的字符串: 

 a:61,b:62

bytes的作用:序列化

向外发送post请求时,字符串必须先转为bytes类型,再传递给post函数

字节序列到字符串:

import "contrib/bonitoo-io/hex"
import "array"

b = "616263"
c = hex.bytes(v: b)//解析为bytes类型

array.from(rows: [{"value":display(v:c)}])

duration时间间隔:

duration是flux脚本里面支持的类型,而不是influxdb里面支持的存储类型。

import "array"
import "date"

//RFC3339格式日期时间:
a = 2022-09-29T05:10:00Z
b = 2022-09-29T05:10:00.001Z
c = 1d2h//1天零2小时
c2 = -1d2h
e = date.add(d:c,to:a)

array.from(rows: [{"value":a},{"value":b},{"value":e}])

类型转换问题:

字符串:

import "array"
import "date"

//RFC3339格式日期时间:
a = 2022-09-29T05:10:00Z
b = 1mo
c = 1d2h//1天零2小时
d = duration(v: c)

array.from(rows: [{"value":display(v:d)}])

整数:

import "array"
import "date"

//RFC3339格式日期时间:
a = 2022-09-29T05:10:00Z
b = 1mo
c = 1000*1000*1000*60*60*24
//直接用整数表示的是纳秒:
d = duration(v: c)

array.from(rows: [{"value":display(v:d)}])

time时间点:

import "array"
import "date"

b = now()//获取当前时间点
c = date.hour(t: now())//返回int类型,把时间对应的小时提取出来

array.from(rows: [{"value":c}])

与时间戳的相互转换:

import "array"
import "date"

a = 1022-01-30T05:10:00.001Z
//时间戳转时间点
b = time(v: 1664401985000*1000*1000)//化成微秒再化成纳秒
//时间点转时间戳
c = uint(v: a)

array.from(rows: [{"value":c}])

字符串:

import "array"
import "date"

a = "ab\"c"//用反斜杠转义

array.from(rows: [{"value":a}])

其他类型转成字符串:

import "strings"
import "array"
import "date"

//判断字符串里面是否包含某个字符串
a = strings.containsStr(v: "This and that", substr: "and")
//
b = strings.joinStr(arr: ["a", "b", "c"], v: ",")
//判断字符串里面是不是一个英文字母(字符串里面只能有一个字符)
c = strings.isLetter(v: "A")

array.from(rows: [{"value":c}])

更多:

Flux standard library | Flux 0.x Documentation

正则表达式:

正则表达式是flux脚本里面支持的类型,而不是influxdb里面支持的存储类型。要展示需要display函数转成字符串。

import "strings"
import "array"
import "date"

//正则表达式里面包含abc或bcd或edf:
a = "abcdefg"
b = /abc|bcd|edf/
c = a =~ b

array.from(rows: [{"value":c}])

字符串匹配其中内容并提取其中内容:

import "regexp"
import "strings"
import "array"
import "date"

a = "abcdefg"
b = /abc|bcd|edf/
c = regexp.findString(r: b, v: a)//返回字符串里面最左边被匹配到的内容。r:正则表达式,v:要被匹配的内容

array.from(rows: [{"value":c}])

字符串转成正则表达式:

import "regexp"
import "array"

a = "abc|bcd"
b = regexp.compile(v:a)
c = "abcdef"

array.from(rows: [{"value":c =~ b}])

整数:

整数和无符号整数的区别是整数可以带正负号。flux语言里面的整数由8个字节表示,因此取值范围是2^63-1~2^63-1。

其他类型与整数的转换:

字符串转整数:

字面值必须是数字。

import "array"

a = int(v: "123")

array.from(rows: [{value: a}])

小数转整数:

只保留整数部分(即截断)。

import "array"

a = int(v: 12.8)

array.from(rows: [{value: a}])

如果要四舍五入:

import "math"
import "array"

a = math.round(x: 12.5)//返回结果是浮点数
b = int(v: a)//转换成整数

array.from(rows: [{value: b}])

整数的16进制表示:

import "contrib/bonitoo-io/hex"
import "math"
import "array"

a = hex.int(v: "a")//传入参数:表示了16进制数字的字符串。在16进制里面a表示10
b = hex.int(v: "a0")//=160

array.from(rows: [{value: a}])

无符号整数:

范围:0~2^64-1

声明无符号整数:

import "contrib/bonitoo-io/hex"
import "math"
import "array"

a = uint(v: 123)

array.from(rows: [{value: a}])

 由于整数最大只能是2^63-1,为了让v的值可以是2^64-1,使用字符串方式声明:

import "contrib/bonitoo-io/hex"
import "math"
import "array"

a = uint(v: "9223372036854775808")

array.from(rows: [{value: a}])

浮点数:

用8个字节表示。在flux语言里面只有float这个类型。

科学计数法:

import "array"

a = float(v: "1.2345e+10")//e表示10的几次方
//正无穷大表示:+Inf
//不是一个数字:Nan

array.from(rows: [{value: a}])

null:

flux语言不支持null类型。解决方法:使用debug函数:

import "array"
import "internal/debug"//前端里面没有定义要自己导包

a = debug.null(type:"string")//得到一个string类型的null值
b = exists a//判断a是不是null。是返回false

array.from(rows: [{value: b}])

4种复合类型

Record(记录):

一个记录是一堆键值对的集合,其中键必须是字符串,值可以是任意类型,在键上没 有空白字符的前提下,键上的双引号可以省略。

import "array"

a = {"name":"tom",age:18,"x y":"20,40"}//record不能直接当做列里面的数据
b = {"name":"jack",age:18,"x y":"20,40"}

//array.from(rows: [{value: display(v:a)}])//因此使用display函数
array.from(rows:[a,b])

因此flux里面的表是由多个record构成的。

访问 Record 里面的数据:

import "array"

a = {"name":"tom",age:18,"x y":"20,40"}
b = {"name":"jack",age:18,"x y":"20,40"}

//1.通过 .属性 的方式
c1 = b.name
//2.["键名"]
c2 = b["age"]

//record里面的属性不能进行动态访问
key_name = "age"
c3 = b[key_name]

array.from(rows: [{value: c}])

判断2个record是否相等:

import "array"

a = {"name":"tom",age:18,"x y":"20,40"}
b = {"name":"jack",age:18,"x y":"20,40"}

c = a == b

array.from(rows: [{value: c}])

拓展一个 record:

import "array"

a = {"name":"tom",age:18,"x y":"20,40"}
b = {"name":"jack",age:18,"x y":"20,40"}

c = {b with age:19,height:111}

array.from(rows: [c])

记录嵌套:

嵌套在flux语法里面支持,在返回结果里面不支持

import "array"

a = {
    name:"tom",
    address:{
        country:"china"
    }
}

array.from(rows: [c])

 记录嵌套可以用来做HTTP请求的JSON数据体。

c = json.encode(v:a)

访问属性:

d = a.address.country

Dictionary(字典):

字典和记录很像,但是 key-value 上的要求有所不同。一个字典是一堆键值对的集合,其中所有键的类型必须相同,且所有值的的类型必须相同,但字典的键不要求一定是字符串。 在语法上,dictionary 需要使用方括号[ ]声明,键的后面跟冒号(:)键值对之间需要使 用英文逗号( , )分隔。

插入/覆盖/删除键值对 :

import "dict"
import "array"

a = ["name":"tony","age":"18"]
b = dict.insert(dict:a,key:"height",value:"200")
c = dict.insert(dict:a,key:"age",value:"19")
d = dict.remove(dict:a,key:"height")

array.from(rows: [{"value":display(v:b)}])

从字典里取值:

import "dict"
import "array"

a = ["name":"tony","age":"18"]
b = dict.get(dict:a,key:"age",default:"244")//如果字典里面没有age这个键,要用默认值替代

array.from(rows: [{"value":display(v:b)}])

字典可以动态访问:

import "dict"
import "array"

a = ["name":"tony","age":"18"]
key_name = "age"
b = dict.get(dict:a,key:key_name,default:"244")//如果字典里面没有age这个键,要用默认值替代

array.from(rows: [{"value":display(v:b)}])

字典的用法:映射 

Array(数组):

数据是一个由相同类型的值构成的有序序列。 在语法上,数组是用方括号[ ]起来的一堆同类型元素,元素之间用英文逗号( , )分隔, 并且类型必须相同。

import "dict"
import "array"

a = ["a","b","c"]
//数组内容是record:
//注意:键一样、值的类型一样才是同类型
b = [{"name":"tom",age:18},{"name":"jack",age:18}]

array.from(rows: [{"value":display(v:a)}])

数组操作:

import "dict"
import "array"

a = [1,2,3]
//数组元素的访问:
b = a[0]
c = length(arr: a)
d = contains(value: 1, set: a)

array.from(rows: [{"value":display(v:b)}])

function(函数):

import "array"

//乘法运算函数
chengfa = (a,b=100) => a * b
x = chengfa(a:4,b:5)

array.from(rows: [{"value":x}])
import "array"

//乘法运算函数
chengfa = (a,b=100) => {
    return a * b
}
x = chengfa(a:4,b:5)

array.from(rows: [{"value":x}])

flux语言里面,函数也是一个类型,因此可以作为返回值。 

类型约束:

自动

flux语言官方文档

flux查询influxdb

from(bucket: "example_query")
  |> range(start: -3h)

序列、表、表流:

表和表流是flux语言的概念,序列是influxdb的概念,在web端influxdb中的数据以表的形式展示。为了flux中的表和influxdb中的序列能够吻合,创建了表流的概念,可以理解为由表形成的数组。

表流(stream)也可以按照重新定义进行分组

filter维度过滤:

from(bucket: "example_query")
  |> range(start: -26h)
  |> filter(fn: (r) => r["_measurement"]=="car", onEmpty: "keep")//影响的是table的编号:是把过滤掉的当做没有还是保留
  |> filter(fn: (r) => (r["code"]=="02"))//用 r["code"] 访问属性

类型转换函数与下划线字段:

通过行协议向example_query中写入:

查询, 

from(bucket: "example_query")
  |> range(start: -5h)
  |> filter(fn: (r) => r["_measurement"]=="test")

发现filed3的value类型被转换成了浮点数: 

 因此,为了不出现这种情况要对field进行过滤,让_value类型保证统一,

from(bucket: "example_query")
  |> range(start: -5h)
  |> filter(fn: (r) => r["_measurement"]=="test")
  |> filter(fn: (r) => r["_field"]=="field1")//要让_value类型保证统一

类型转换:

让10转成整数类型:

from(bucket: "example_query")
  |> range(start: -5h)
  |> filter(fn: (r) => r["_measurement"]=="test")
  |> filter(fn: (r) => r["_field"]=="field2")//要让_value类型保证统一
  |> toInt()

约定:

上面的toInt函数没有指定任何字段,直接对value这个字段进行了类型转换的处理。这种函数类型称之为约定,使用下划线开头的字段都带有某种约定。

map函数:

遍历表流里面每一条数据

import "array"

//手动创建一个表流:
array.from(rows: [{"name":"tony"},{"name":"jack"}])
//返回一个record类型
//   |> map(fn: (r)=>({"name":"tony2"}))
  |> map(fn: (r)=>{
     return if r["name"] == "tony" then {"_name":"tony不是jack"} else {"_name":"jack不是tony"}
  })

自定义管道函数:

big100 = (table=<-) => {
  return table
    |> map(fn: (r)=>({r with "_value":r["_value"]*100.0}))
}
chengfa = (x,y) => x*y

from(bucket:"test_init")
|>range(start:-1h)
|>filter(fn:(r)=>r["_measurement"]=="go_goroutines")
|>big100()
big100 = (table=<-,x=100.0) => {
  return table
    |> map(fn: (r)=>({r with "_value":r["_value"]*x}))
}
chengfa = (x,y) => x*y

from(bucket:"test_init")
|>range(start:-1h)
|>filter(fn:(r)=>r["_measurement"]=="go_goroutines")
|>big100(x:2.0)

这里需要强调的是,管道函数的第一个参数必须写成 table=<-,它表示通过管道符输 入进来的表流数据,需要注意,table 并不一定写成 table 但是=<-的格式绝对不能变。 

window和aggregateWindow:

开窗改变了原有序列,把整个表流按照窗口的开始时间和截止时间进行了重新分组。

from(bucket: "example02")
  |> range(start: -10m)
  |> filter(fn: (r) => r["_measurement"] == "cpu")
  |> filter(fn: (r) => r["_field"] == "usage_user")
  //开窗改变了原有序列,把整个表流按照窗口的开始时间和截止时间进行了重新分组
  |> window(period: 30s)//period:时间间隔间隔,每隔30s开一次窗;every:窗口宽度,默认等于period
  //开窗之后可以做聚合操作:
  |> max()//默认对value操作

aggregateWindow:

aggregateWindow 不会影响原来的序列结构

  |> aggregateWindow(period: 30s, every: 30s, fn: max)

yield和join:

当 flux 脚本中出现未被赋值给某个变量的表流时,InfluxDB 执行 FLUX 脚本时会自动 帮他们在管道的最后面加上|> yield(name: "_result")函数,yield 函数其实是指定了我们当前 这个表流是整个 FLUX 脚本最后返回的结果,而且这个结果的名字叫"_result"。

from(bucket: "example02")
  |> range(start: -10m)
  |> filter(fn: (r) => r["_measurement"] == "cpu")
  |> filter(fn: (r) => r["_field"] == "usage_user")
  |> aggregateWindow(period: 30s, every: 30s, fn: max)
  |> yield(name: "tony")

from(bucket: "example02")
  |> range(start: -10m)
  |> filter(fn: (r) => r["_measurement"] == "cpu")
  |> filter(fn: (r) => r["_field"] == "usage_user")
  |> aggregateWindow(period: 30s, every: 30s, fn: max)
  |> yield(name: "jack")

具体见文档。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值