InfluxDB v2.6.0正则过滤标签遇解析错误求助
解决Flux查询中用动态列表过滤标签的正则错误问题
问题原因
你遇到的错误是因为ldevname是一个Flux表结构,直接插入正则表达式/${ldevname}/时,表会被强制转成包含换行、分隔符的字符串,导致正则引擎无法识别,抛出重复量词的语法错误。
解决方案
需要先将查询得到的ldevname列表转换成合法的正则表达式字符串,再用于过滤:
步骤1:提取ldevname列表为字符串数组
使用reduce函数将表中的所有_value值收集到一个数组中:
ldevnameList = from(bucket: v.bucket) |> range(start: -365d) |> filter(fn: (r) => r._measurement == "LDEV_CNF") |> filter(fn: (r) => r.poolid == "${pool}") |> keep(columns: ["_value"]) |> reduce( fn: (r, accumulator) => ({list: accumulator.list ++ [r._value]}), identity: {list: []} ) |> findRecord(fn: (key) => true, idx: 0) |> (r => r.list)
步骤2:生成正则表达式字符串
将数组元素用|连接,构造成正则的备选匹配模式:
regexPattern = "(?:" |> string.concat(v: string.join(arr: ldevnameList, t: "|")) |> string.concat(v: ")" )
步骤3:在主查询中使用正则过滤
用regexPattern作为匹配条件,通过regex.regexpString将字符串转为正则类型:
from(bucket: v.bucket) |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == "LDEV" and r._field == "LDEV_IOPS") |> filter(fn: (r) => r["ldevID"] =~ regex.regexpString(v: regexPattern))
完整可运行代码
// 1. 获取并转换ldevname为字符串数组 ldevnameList = from(bucket: v.bucket) |> range(start: -365d) |> filter(fn: (r) => r._measurement == "LDEV_CNF") |> filter(fn: (r) => r.poolid == "${pool}") |> keep(columns: ["_value"]) |> reduce( fn: (r, accumulator) => ({list: accumulator.list ++ [r._value]}), identity: {list: []} ) |> findRecord(fn: (key) => true, idx: 0) |> (r => r.list) // 2. 生成正则匹配串 regexPattern = "(?:" |> string.concat(v: string.join(arr: ldevnameList, t: "|")) |> string.concat(v: ")" ) // 3. 主查询过滤 from(bucket: v.bucket) |> range(start: v.timeRangeStart, stop: v.timeRangeStop) |> filter(fn: (r) => r._measurement == "LDEV" and r._field == "LDEV_IOPS") |> filter(fn: (r) => r["ldevID"] =~ regex.regexpString(v: regexPattern))
补充说明
- 若需要精确匹配(避免
ldevID是列表元素的子串),可修改正则为:regexPattern = "^(?:" |> string.concat(v: string.join(arr: ldevnameList, t: "|")) |> string.concat(v: ")$" - 若
ldevname包含正则特殊字符(如.,*,+),需先转义每个元素:ldevnameList = from(bucket: v.bucket) // ... 前面步骤不变 |> map(fn: (r) => ({_value: regex.escape(v: r._value)})) |> reduce(/* ... 同前 */)
内容的提问来源于stack exchange,提问作者greg
相关产品推荐
相关产品推荐

