mcpField
D
dt-dql-essentials

dt-dql-essentials

github.com/dynatrace数据与数据库1692.9k 次安装今天更新
代码仓库

关于 dt-dql-essentials

DQL Essentials 是面向 Dynatrace DQL 使用者的技能,帮助编写查询并查阅语法、函数和任务相关参考。内容涵盖查询模式、优化及常见语法陷阱。

主要功能

  1. 01按任务查找 DQL 参考
  2. 02涵盖命令与函数索引
  3. 03提供查询优化指导
  4. 04说明语法陷阱与正确写法

适用场景

  1. 01发现可查询的数据
  2. 02编写筛选与聚合查询
  3. 03优化查询效率
  4. 04处理数组和时间序列

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dynatrace/dynatrace-for-ai --skill dt-dql-essentials

安装后在 Claude Code 中输入/dt-dql-essentials确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
discovery.md
iterative-expressions.md
operators.md
optimization.md
semantic-dictionary.md
smartscape-topology-navigation.md
references/dql/
dql-commands.md
dql-data-types.md
dql-functions-aggregation.md
dql-functions-array.md
dql-functions-bitwise.md
dql-functions-boolean.md
dql-functions-cast.md
dql-functions-constant.md
dql-functions-conversion.md
dql-functions-create.md
dql-functions-cryptographic.md
dql-functions-entities.md
dql-functions-expression-timeseries.md
dql-functions-flow.md
dql-functions-general.md
dql-functions-get.md
dql-functions-iterative.md
dql-functions-mathematical.md
dql-functions-network.md
dql-functions-smartscape.md
dql-functions-string.md
dql-functions-time.md
dql-functions-timeseries.md
dql-parameter-value-types.md

详细介绍

DQL 基础技能

DQL 是一种基于管道的查询语言。查询使用 | 将命令串联起来,以筛选、转换和聚合数据。DQL 的语法独特,与 SQL 不同——编写任何 DQL 查询前,请先加载此技能。


何时加载参考资料

开始处理特定任务前,请加载相关参考资料:

任务必读内容
发现数据references/discovery.md
字段名称、命名空间、数据模型、稳定性级别、查询模式references/semantic-dictionary.md
查询优化——让查询更快、更高效或成本更低,减少消耗和扫描的数据(尽早筛选、分桶筛选、时间范围、字段选择、采样、基数)references/optimization.md
使用 Smartscape 拓扑导航发现实体之间的关系references/smartscape-topology-navigation.md
summarize 和 makeTimeseries 模式(分桶、日历月)references/summarization.md
数组和时间序列操作(arrayFilter、collectArray、迭代)references/iterative-expressions.md
条件逻辑(if/else 链)、coalesce、字符串/日期辅助函数references/useful-expressions.md
in 运算符(子查询)、完整的 @ 时间对齐单位表references/operators.md
matchesValue、matchesPhrase、matchesPattern、in()——字符串模式匹配、正则表达式、数组匹配、通配符、大小写敏感性references/string-matching.md

DQL 参考索引

使用此索引,从函数组(例如时间函数、转换)找到其详细规范,或从函数名称找到对应的规范文件。

描述条目
数据类型array、binary、boolean、double、duration、long、record、string、timeframe、timestamp、uid
参数值类型bucket、dataObject、dplPattern、entityAttribute、entitySelector、entityType、enum、executionBlock、expressionTimeseriesAggregation、expressionWithConstantValue、expressionWithFieldAccess、fieldPattern、filePattern、identifierForAnyField、identifierForEdgeType、identifierForFieldOnRootLevel、identifierForNodeType、joinCondition、jsonPath、metricKey、metricTimeseriesAggregation、namelessDplPattern、nonEmptyExecutionBlock、prefix、primitiveValue、simpleIdentifier、tabularFileExisting、tabularFileNew、url
命令append、data、dedup、describe、expand、fetch、fields、fieldsAdd、fieldsFlatten、fieldsKeep、fieldsRemove、fieldsRename、fieldsSnapshot、fieldsSummary、filter、filterOut、join、joinNested、limit、load、lookup、makeTimeseries、metrics、parse、search、smartscapeEdges、smartscapeNodes、sort、summarize、timeseries、traverse
函数 — 聚合avg、collectArray、collectDistinct、correlation、count、countDistinct、countDistinctApprox、countDistinctExact、countIf、max、median、min、percentRank、percentile、percentileFromSamples、percentiles、stddev、sum、takeAny、takeFirst、takeLast、takeMax、takeMin、variance
函数 — 数组arrayAvg、arrayConcat、arrayCumulativeSum、arrayDelta、arrayDiff、arrayDistinct、arrayFirst、arrayFlatten、arrayIndexOf、arrayLast、arrayLastIndexOf、arrayMax、arrayMedian、arrayMin、arrayMovingAvg、arrayMovingMax、arrayMovingMin、arrayMovingSum、arrayPercentile、arrayRemoveNulls、arrayReverse、arraySize、arraySlice、arraySort、arraySum、arrayToString、vectorCosineDistance、vectorInnerProductDistance、vectorL1Distance、vectorL2Distance
函数 — 位运算bitwiseAnd、bitwiseCountOnes、bitwiseNot、bitwiseOr、bitwiseShiftLeft、bitwiseShiftRight、bitwiseXor
函数 — 布尔值exists、in、isFalseOrNull、isNotNull、isNull、isTrueOrNull、isUid128、isUid64、isUuid
函数 — 类型转换asArray、asBinary、asBoolean、asDouble、asDuration、asIp、asLong、asNumber、asRecord、asSmartscapeId、asString、asTimeframe、asTimestamp、asUid
函数 — 常量e、pi
函数 — 转换toArray、toBoolean、toDouble、toDuration、toIp、toLong、toSmartscapeId、toString、toTimeframe、toTimestamp、toUid、toVariant
函数 — 创建array、duration、ip、record、smartscapeId、timeframe、timestamp、timestampFromUnixMillis、timestampFromUnixNanos、timestampFromUnixSeconds、uid128、uid64、uuid
函数 — 加密hashCrc32、hashMd5、hashSha1、hashSha256、hashSha512、hashXxHash32、hashXxHash64
函数 — 实体classicEntitySelector、entityAttr、entityName
函数 — 表达式的时间序列聚合avg、count、countDistinct、countDistinctApprox、countDistinctExact、countIf、end、max、median、min、percentRank、percentile、percentileFromSamples、start、sum
函数 — 流程控制coalesce、if
函数 — 通用jsonField、jsonPath、lookup、parse、parseAll、type
函数 — 获取arrayElement、getEnd、getHighBits、getLowBits、getStart
函数 — 迭代iAny、iCollectArray、iIndex
函数 — 数学abs、acos、asin、atan、atan2、bin、cbrt、ceil、cos、cosh、degreeToRadian、exp、floor、hexStringToNumber、hypotenuse、log、log10、log1p、numberToHexString、power、radianToDegree、random、range、round、signum、sin、sinh、sqrt、tan、tanh
函数 — 网络ipIn、ipIsLinkLocal、ipIsLoopback、ipIsPrivate、ipIsPublic、ipMask、isIp、isIpV4、isIpV6
函数 — SmartscapegetNodeField、getNodeName
函数 — 字符串concat、contains、decodeBase16ToBinary、decodeBase16ToString、decodeBase64ToBinary、decodeBase64ToString、decodeUrl、encodeBase16、encodeBase64、encodeUrl、endsWith、escape、getCharacter、indexOf、lastIndexOf、levenshteinDistance、like、lower、matchesPattern、matchesPhrase、matchesRegex、matchesValue、punctuation、replacePattern、replaceString、splitByPattern、splitString、startsWith、stringLength、substring、trim、unescape、unescapeHtml、upper
函数 — 时间formatTimestamp、getDayOfMonth、getDayOfWeek、getDayOfYear、getHour、getMinute、getMonth、getSecond、getWeekOfYear、getYear、now、unixMillisFromTimestamp、unixNanosFromTimestamp、unixSecondsFromTimestamp
函数 — 指标的时间序列聚合avg、count、countDistinct、end、max、median、min、percentRank、percentile、start、sum

Syntax Pitfalls

❌ 错误✅ 正确问题
filter field in ["a", "b"]filter in(field, {"a", "b"})在 DQL 中,[ 和 ] 用于括起子查询,但不用于括起静态数组字面量。静态值请使用 {} 或 array()。
filter: { in(field, [sub-query]) }(例如在 timeseries filter: 中)filter: { field in [sub-query] }in() 不接受执行块作为参数。当右侧是子查询(执行块)时,请使用 in 运算符:field in [execution block]。
by: severity, statusby: {severity, status}在 by: 子句(summarize、makeTimeseries 等)中,字段列表必须用花括号括起。
contains(toLowercase(field), "err")contains(field, "err", false)区分大小写匹配时,不要用 lower() 包裹。contains() 内置了第三个位置参数 caseSensitive(默认值为 true)。
filter name == "*serv*9*"filter matchesValue(name, "*serv*") and matchesValue(name, "*9*")== 不支持通配符。matchesValue() 支持 * 通配符,但只能放在模式的开头和/或结尾;若要表达字符串中间的通配符意图,请拆分为多个调用并用 and 连接。
在字符串字段上使用 matchesValue(field, "prod")contains(field, "prod")不使用通配符时,matchesValue() 会执行精确(不区分大小写)匹配,因此无法找到 "production"。子字符串匹配请使用 contains()(通配符匹配则使用 matchesValue(field, "*prod*"))。
iAny(matchesValue(arr[], "x") OR matchesValue(arr[], "y"))matchesValue(arr, {"x", "y"})matchesValue 的第一个参数可以是数组字段,第二个参数可以是数组字面量 {},无需使用 iAny 或 []。同样,若要合并同一字段上的多个 contains(f, x) OR contains(f, y),请使用 matchesValue(f, {"*x*", "*y*"})。
iAny(matchesPhrase(arr[], "phrase"))matchesPhrase(arr, "phrase")matchesPhrase 原生支持遍历数组字段,可去掉 iAny( 和 []。注意:第二个参数必须是静态字符串;matchesPhrase(f, array("a","b")[]) 会导致运行时错误。
在较短或常见词元上使用 contains(field, "pip")matchesPhrase(field, "pip")contains 只匹配子字符串,因此 "pip" 也会匹配 "pipenv"、"gripping"。matchesPhrase 会对字符串进行词元化,仅匹配完整单词,从而减少误报。
iAny(in(lower(arr[]), array("a", "b")))matchesValue(arr, {"a", "b"}, caseSensitive: false)matchesValue 默认不区分大小写,无需使用 lower()、in() 或 iAny 包装。此处显式写出 caseSensitive: false,只是为了与被替换的 lower() 意图一致。
iAny(f1[] == "a" AND f2[] == "b"),遍历两个独立数组in(f1, "a") AND in(f2, "b")多数组 iAny 是成对匹配,而非笛卡尔积:会将 f1[] 的第 i 个元素与 f2[] 的第 i 个元素进行测试。如果数组长度不同,结果为 null。请改用独立的 in() 检查。参见 references/iterative-expressions.md。
toLowercase(field)lower(field)函数名是 lower(),不是 toLowercase()。只有类型转换函数使用 to 前缀(toString()、toLong() 等)。
arrayAvg(field[]) 或 arraySum(field[])arrayAvg(field) 或 field[]field[] = 逐元素迭代表达式(数组→数组);arrayAvg(field) = 折叠为标量(数组→单个值)。切勿混用;arrayAvg(field[]) 在语义上是错误的。
lookup 或 join 之后使用 my_fieldlookup.my_field / right.my_fieldlookup 默认会在新增字段前加上 lookup. 前缀(可通过 prefix: 配置)。join 会在右侧字段前加上 right. 前缀。
substring(field, 0, 200)substring(field, from: 0, to: 200)第一个参数(表达式)是位置参数,但 from: 和 to: 是可选的命名参数,必须写出参数名。
filter host = "A"filter host == "A"DQL 使用 == 进行相等比较,而非 =。单个 = 用于赋值(例如在 fieldsAdd、summarize 别名中)。
fetch logs, from: toTimestamp('2026-01-01')fetch logs, from: -24hfrom:/to: 接受时长字面量(例如 -24h、-7d)或 now() 表达式,不接受 toTimestamp()。绝对时间范围请使用 timeframe: "start/end"(ISO 8601)。
filter log.level == "ERROR"filter loglevel == "ERROR"日志严重性字段是 loglevel(没有点号);log.level 不存在。
sort count() descsort `count()` desc带特殊字符(如括号)的字段必须用反引号括起。
length(field)stringLength(field)DQL 的字符串长度函数是 stringLength,不存在 length()。
metrics dt.host.cpu.usagetimeseries avg(dt.host.cpu.usage)metrics 加载的是指标元数据,而非指标值;请使用 timeseries 获取数据。
join [...], on:{left.a.b == right.a.b}join [...], on:{left[`a.b`] == right[`a.b`]}在 join/lookup 条件中,带点号的字段名必须使用带反引号的方括号表示法。
fieldsSummary(不带参数)fieldsSummary field1, field2fieldsSummary 至少需要一个字段参数。
timeseries 使用 percentile/median/percentRank,但没有结果在 timeseries 命令中添加 rollup: avg(或 min/max/sum)对 gauge/count 指标使用这三个函数时,必须指定 rollup:;否则查询会静默返回空结果。
summarize p95 = percentile(duration, 95, rollup: avg)summarize p95 = percentile(duration, 95)rollup: 是**仅适用于 timeseries**的参数。在日志/spans/events 上对同名聚合使用 summarize 时会因 UNKNOWN_PARAMETER_DEFINED 被拒绝。只有在 timeseries 中聚合指标时才添加 rollup:。
filter array.contains(field, "v") 或 arrayContains(field, "v")filter in(field, {"v"})DQL 中不存在这两个函数;它们是从 Python/Java/SQL 臆造出来的。in() 已原生支持匹配数组类型字段(例如 dt.davis.problems 上的 k8s.namespace.name):只要 needle 中的任一元素与 haystack 中的任一元素匹配,就会返回 true。参见 references/iterative-expressions.md。
字段为数组类型时使用 filter k8s.namespace.name == "ns"filter in(k8s.namespace.name, {"ns"})对数组类型字段使用 == 不会匹配任何内容;它会无报错地返回零行,看起来像是“没有数据”,而不是写法错误。dt.davis.problems 上的 k8s.* 字段是数组。精确匹配成员请使用 in() 或 matchesValue(field, {...})。
parseJson(field) 或 extractJsonField(field, jsonPath: "$.x")parse field, "JSON:parsed",然后使用 parsed[x]这两个函数都不存在。字符串字段中嵌入的 JSON 应使用 parse 命令和 JSON DPL 匹配器解包,然后通过方括号表示法访问。
filter hour(timestamp) == 4/minute(timestamp)filter getHour(timestamp) == 4/getMinute(timestamp)不存在 hour()/minute() 函数。get* 系列返回数字,因此可以进行数值比较和范围比较。不要替换为 formatTimestamp(timestamp, format: "HH");它返回的是字符串,因此 == 4 会静默地匹配不到任何内容。
在 dt.entity.* 上使用 fields fromRelationships, toRelationships, containerImageTag先使用 describe dt.entity.<type>,再选择实际字段传统实体对象不会公开 Entities REST API 的属性名称。必须通过 describe <dataObject> 查找字段名,而不能根据 API 负载猜测。
by: {bin(timestamp, 1h)},然后使用 sort `bin(timestamp,1h)`by: {t = bin(timestamp, 1h)},然后使用 sort tDQL 会将自动生成的分组键名称规范化为 bin(timestamp, 1h),逗号后始终带空格,不受表达式原写法影响。省略空格的反引号引用会触发 FIELD_DOES_NOT_EXIST。请始终为分组键添加别名。
fetch spans | ... by: {bin(timestamp, 1h)}fetch spans | ... by: {t = bin(start_time, 1h)}spans 没有 timestamp 字段;其时间字段是 start_time 和 end_time。引用 timestamp 会根据所在位置报错或产生空值。
lookup [...], fields: {`dotted.name`}lookup [...], fields: {dotted.name}在 lookup 的 fields: 参数中不要用反引号括起字段名,否则会导致 PARSE_ERROR。
data record(key: "val")data record(key = "val")record() 的命名字段使用 =,而非 :;: 用于 rollup: 之类的命令参数。
getNodeField(dt.smartscape.host, "tags")["tag.key"]getNodeField(dt.smartscape.host, "tags")[tag.key]在此标签映射访问模式中,方括号键必须使用不带引号的标识符语法;带引号的键会导致解析错误。
by: {dt.entity.host} 或 dt.entity.*by: {dt.smartscape.host} 或 dt.smartscape.*dt.entity.* 已弃用;新查询一律使用 dt.smartscape.*。

Fetch 命令 → 数据模型

DQL 查询以 fetch <data_object> 或 timeseries 开头。没有 fetch dt.metric——指标使用 timeseries。

Fetch 命令数据模型关键字段 / 备注
fetch spans分布式追踪span.*、service.*、http.*、db.*、code.*、exception.*
fetch logs日志事件log.*、k8s.*、host.*——消息正文是 content,严重性是 loglevel(不是 log.level)
fetch eventsDAVIS / 基础设施事件event.*、dt.smartscape.*
fetch bizevents业务事件event.*、自定义字段
fetch security.events安全事件vulnerability.*、event.*
fetch user.sessionsRUM 会话dt.rum.*、browser.*、geo.*
fetch user.eventsRUM 单个事件页面浏览、点击、请求、错误
fetch user.replays会话回放录制
fetch application.snapshots应用程序快照
fetch dt.davis.eventsDavis 检测到的事件
fetch dt.davis.problemsDavis 检测到的问题
timeseries avg(metric.key)指标不是 fetch——带连字符的键需要使用反引号:timeseries sum(`my.metric-name`)
smartscapeNodes "HOST"拓扑不是 fetch——类型包括:HOST、SERVICE、K8S_CLUSTER 等

dt.entity.* 已弃用——新查询请使用 dt.smartscape.* 和 smartscapeNodes。

发现所有可用的数据对象:fetch dt.system.data_objects | fields name, display_name, type

→ 完整字段命名空间请参阅 references/semantic-dictionary.md


samplingRatio 参数

fetch 支持 samplingRatio: 参数,可减少读取的数据量——这有助于提升大型数据集的查询性能。

fetch spans, samplingRatio:100   // reads ~1% of data

**允许的值:**取决于具体的数据对象,范围从 1、10、100、1000、10000 到 100000;最高级别仅适用于 logs 和 spans。

对于 spans、user.events 和 user.sessions,采样采用分层方式:在较高比例(例如 100)下纳入的记录,保证也会出现在较低比例(例如 10、1)中,反之则不成立。这意味着不同采样比例下的结果彼此是子集关系。其他所有非指标数据对象均按记录独立采样,因此不同采样比例下的结果不构成子集关系。

实际应用的比例可通过 dt.system.sampling_ratio 字段获取。使用此字段,可将采样计数外推为实际总数:

fetch logs, samplingRatio:10
| summarize count_extrapolated = sum(dt.system.sampling_ratio)

Timeseries 聚合函数

timeseries 命令仅支持以下聚合函数:

函数描述
sum每个时间槽内指标数据点的总和
avg每个时间槽内指标数据点的平均值
min每个时间槽内指标数据点的最小值
max每个时间槽内指标数据点的最大值
count每个时间槽内指标数据点的数量
percentile(metric, N)每个时间槽内的第 N 百分位数。需要 rollup:——见下文。
median(metric)每个时间槽内的第 50 百分位数(= percentile(metric, 50))。需要 rollup:。
percentRank(metric, value)每个时间槽内某个值的百分位排名。需要 rollup:。
countDistinct(metric)每个时间槽内近似去重计数(仅限基数指标;不接受 rollup:)。

辅助函数(与聚合函数搭配使用):start()、end()。

timeseries 不支持:countIf、collectArray、stddev、variance、takeAny、takeFirst、takeLast——请使用 summarize 或 makeTimeseries。

rollup: 参数

指标会在写入时预聚合。rollup: 用于控制每个时间槽中如何合并原始数据点。percentile、median、percentRank 必须使用此参数,否则查询会静默返回空结果。avg/min/max/sum/count 无需 rollup:。

rollup: 是仅适用于 timeseries 的参数,只能用于指标聚合。在事件数据(日志、跨度、事件)的 summarize 中,同名的聚合函数不接受此参数:summarize p95 = percentile(duration, 95, rollup: avg) 会报错 UNKNOWN_PARAMETER_DEFINED。在 summarize 中,请使用不带 rollup: 的 percentile(field, N)。

单个聚合:在命令级别使用 rollup:。多个聚合(使用 {}):rollup: 必须放在每个函数调用内部(命令级别的 rollup: 会导致 UNKNOWN_PARAMETER_DEFINED):

timeseries p90 = percentile(dt.process.handles.file_descriptors_percent_used, 90), rollup: avg
timeseries {
  p90 = percentile(dt.process.handles.file_descriptors_percent_used, 90, rollup: avg),
  med = median(dt.process.handles.file_descriptors_percent_used, rollup: avg),
  avg_val = avg(dt.process.handles.file_descriptors_percent_used)
}, by: {dt.smartscape.host}

取值:avg(仪表盘指标)、min、max、sum(计数器)、total。

时序数据转标量

将时序数据折叠为标量有两种方法。如果只需要单个聚合值,优先使用 scalar:true 参数,因为它效率更高,不会生成数组。只有在同一查询中既需要完整序列又需要派生标量时,才使用数组函数。

首选:在聚合函数中使用 scalar:true

将 scalar:true 传递给任意时序聚合函数。结果字段会包含单个值,而不是数组,并且不会分配中间数组:

timeseries avg_cpu = avg(dt.host.cpu.usage, scalar:true), by:{dt.smartscape.host}
timeseries {
  avg_cpu = avg(dt.host.cpu.usage, scalar:true),
  max_cpu = max(dt.host.cpu.usage, scalar:true)
}, by:{dt.smartscape.host}

备用方案:在 fieldsAdd 中使用数组函数

如果需要在派生标量的同时保留完整的时间序列数组,请在后续的 | fieldsAdd 中使用数组函数:

函数说明
arrayAvg(arr)数组中所有值的平均值
arraySum(arr)所有值的总和
arrayMin(arr)最小值
arrayMax(arr)最大值
arrayMedian(arr)中位数
arrayPercentile(arr, N)第 N 百分位数(0–100)
arrayLast(arr)最后一个非空值(最新的数据点)
arrayFirst(arr)第一个非空值(最早的数据点)
timeseries cpu = avg(dt.host.cpu.usage), by:{dt.smartscape.host}
| fieldsAdd avg_cpu = arrayAvg(cpu), max_cpu = arrayMax(cpu)

时间对齐(@ 运算符)

@ 运算符会将时间戳对齐到某个边界,Agent 经常会用错。

表达式含义
now()@h当前时间,按小时边界对齐
now()@d今天午夜
now()@w1本周星期一
now()-2h@h2 小时前,按小时对齐(先偏移,再对齐)

规则:

  • 顺序:先偏移,再对齐——now()-2h@h,而不是 now()@h-2h
  • @ 和单位之间不能有空格——使用 now()@h,而不是 now() @h
  • m 表示分钟,M 表示月——请勿混淆

→ 完整的 timeseries 聚合和 rollup: 规则,请参阅 references/dql/dql-functions-timeseries.md → arrayAvg / arrayMax / arrayPercentile / … 规范,请参阅 references/dql/dql-functions-array.md


实体与 Smartscape 模式

实体字段按类型划分作用域 — 不存在 entity.id。使用 smartscapeNodes 查询拓扑。

实体数据中的 ID 字段smartscapeNodes 类型
主机dt.smartscape.host"HOST"
服务dt.smartscape.service"SERVICE"
进程dt.smartscape.process"PROCESS"
K8s 集群dt.smartscape.k8s_cluster"K8S_CLUSTER"

使用 toSmartscapeId() 将字符串转换为 ID(必需!)。

→ references/smartscape-topology-navigation.md


makeTimeseries 命令

makeTimeseries 根据事件数据(日志、跨度、bizevents)构建按时间分桶的序列。与查询预先摄取指标的 timeseries 不同,makeTimeseries 会在管道中聚合数据。

不要将 timeseries 直接传入 makeTimeseries — 这会因 INVALID_IMPLICIT_TIME_DEFAULT 而失败。若要重新聚合指标数据,请使用 start() + expand(参见 references/summarization.md)。

fetch logs
| makeTimeseries
    total = count(),
    errors = countIf(loglevel == "ERROR"),
    interval: 5m,
    by: {k8s.cluster.name}
| fieldsAdd error_rate = errors[] * 100.0 / total[]

关键参数:interval:、by:{}、from:/to:、bins:、time:(时间戳字段)、spread:(仅适用于 count/countIf)、nonempty:。

→ references/summarization.md,了解完整的 makeTimeseries 模式和 summarize 分桶方式 → references/iterative-expressions.md,了解时间序列数组操作


字符串匹配函数

DQL 有四个主要函数用于字符串和数组模式匹配。完整指南和快速参考表请参阅 references/string-matching.md。

  • matchesValue(field, {"pattern*", "*other*"}) — 通配符匹配(开头/结尾的 *)。第一个参数接受数组字段,第二个参数接受数组字面量 {} — 无需 iAny 或 []。默认不区分大小写(使用 caseSensitive: true 可强制区分大小写)。可替代 contains() + iAny 链式调用和 lower() 变通方法。
  • matchesPhrase(field, "token") — 将字符串拆分为词元并匹配完整单词,不同于只做子字符串匹配的 contains()。第一个参数原生支持数组字段;第二个参数必须是静态字符串(数组展开会导致运行时错误)。
  • in(field, array("a", "b")) — 集合成员判断。两个参数都接受数组,因此可用于检查重叠/交集。

链式 Lookup 模式

每个未设置 fields 参数的 lookup 命令,都会在添加新字段前移除所有以此前缀开头的现有字段(默认值:lookup.)。链式调用多个 lookup 时,请使用 fields 参数或自定义前缀来保留结果:

选项 1(默认):所需字段已知。

fetch bizevents
// Step 1: First lookup — enrich orders with product info
| lookup [fetch bizevents
    | filter event.type == "product_catalog"
    | fields product_id, category],
  sourceField: product_id, lookupField: product_id, fields: {product_id, product_category = category}

// Step 2: Second lookup — specify fields with a different name
| lookup [fetch bizevents
    | filter event.type == "warehouse_stock"
    | fields category, warehouse_region],
  sourceField: product_category, lookupField: category, fields: {warehouse_region, warehouse_category = category}

4 个 lookup 字段 product_id、product_category、warehouse_region 和 warehouse_category 均可用。 如果没有 fields:{...} 参数,这些字段会添加 lookup. 前缀,第二个 lookup 命令会删除第一个命令添加的字段。

选项 2:保留 lookup 中的所有字段。

fetch bizevents
// Step 1: First lookup — enrich orders with product info
| lookup [fetch bizevents
    | filter event.type == "product_catalog"
    | fields product_id, category],
  sourceField: product_id, lookupField: product_id, prefix: "product."

// Step 2: Second lookup — specify fields with a different prefix
| lookup [fetch bizevents
    | filter event.type == "warehouse_stock"
    | fields category, warehouse_region],
  sourceField: product_category, lookupField: category, prefix: "warehouse."

新字段为:product.product_id、product.category、warehouse.category、warehouse.warehouse_region。 原始来源中所有以 product. 或 warehouse. 开头的字段都会被移除。 如果没有专用的 prefix,两个 lookup 命令都会使用相同前缀(lookup.),第二个 lookup 会丢弃第一个 lookup 的结果 — 导致字段为空。


makeTimeseries 命令

makeTimeseries 可根据事件数据(日志、跨度、业务事件)生成按时间分桶的序列。与查询预先摄取的指标的 timeseries 不同,makeTimeseries 会在管道中聚合数据。

不要将 timeseries 直接传入 makeTimeseries——这样会因 INVALID_IMPLICIT_TIME_DEFAULT 而失败。若要重新聚合指标数据,请使用 start() + expand(参见 references/summarization.md)。

fetch logs
| makeTimeseries
    {total = count(),
    errors = countIf(loglevel == "ERROR")},
    interval: 5m,
    by: {k8s.cluster.name}
| fieldsAdd error_rate = errors[] * 100.0 / total[]

关键参数:interval:、by:{}、from:/to:、bins:、time:(时间戳字段)、spread:(仅适用于 count/countIf)、nonempty:。→ 完整规范请参见 references/dql/dql-commands.md。

使用 spread: 创建实体存在时间线:

smartscapeNodes "HOST"
| makeTimeseries concurrently_existing_hosts = count(), spread: lifetime

→ 时间序列数组操作请参见 references/iterative-expressions.md


时间范围规范

访问数据需要指定时间范围。 可在 UI 中指定,也可通过 REST API 参数指定,或在 DQL 查询中显式使用一对参数:from: 和 to:(若省略其中一个,默认值为 now());也可以改用单个 timeframe: 参数。 时间范围可以使用绝对值或相对于当前时间的表达式表示。时间对齐运算符(@)可用于将时间戳舍入到时间单位边界——完整详情请参见 references/operators.md。

示例
from:now()-1h@h, to:now()@h     // last complete hour
from:now()-1d@d, to:now()@d     // yesterday complete
from:now()@M                    // this month so far, till now
from:now()-2h@h                 // go back 2 hours, then align to hour boundary

完整的 @ 对齐单位表(包括 m 与 M 的区别、星期几变体 w1–w7,以及 @3h 等因子规则)请参见 references/operators.md。

绝对时间戳

使用 ISO 8601 格式:

from:"2024-01-15T08:00:00Z", to:"2024-01-15T09:00:00Z"

修改时间

关键概念
  • DQL 有 3 种与时间相关的专用类型:
    • timestamp — 内部以距纪元以来的纳秒数保存,但对外显示为特定时区的日期/时间
    • timeframe — 一对时间戳(开始和结束)
    • duration — 内部以纳秒数保存,但对外显示为缩放到合理单位的时长(例如 ms、分钟、天)
规则
  • 时间戳相减会得到时长:timestamp - timestamp → duration
  • 时长除以时长会得到 double:例如 2h / 1m = 120.0
  • 标量乘以时长会得到时长:例如 no_of_h * 1h → duration
  • 提取时间元素(小时、月中的日期等)时:
    • ✅ 使用时间函数。它们能够正确处理日历和时区,包括夏令时。
    • ❌ 避免使用 formatTimestamp 提取时间组成部分。
    • ❌ 避免将时间戳和时长转换为 double/long 后,再使用除法、取模运算以及表示纳秒时间单位的常量。

参考资料

评论

支持 Markdown