TL;DR InfluxDB技术技巧 — 按标签或字段聚合以及取消分组

导航至

你对时序数据库感兴趣,并决定探索InfluxDB Cloud或InfluxDB v2。也许你刚刚创建了一个免费账户或下载了二进制文件,现在你正在尝试使用InfluxDB用户界面(UI)并学习Flux。对于初学者来说,最难理解的是Flux查询或带注释的CSV的返回结果。本博客TL;DR InfluxDB技术技巧 – 如何解释带注释的CSV中提供了带注释的CSV的详细解释,但今天我们将专注于理解分组键及其如何影响表格流。换句话说,我们将学习

  • 如何使用示例数据集探索Flux
  • 分组键是什么以及分组键如何确定你的带注释CSV输出中的表数量
  • 如何使用group() Flux函数来更改分组
  • 如何通过利用group()函数来分组和取消分组数据来对字段或度量进行聚合

本TL;DR的TL;DR:使用空的group() Flux函数取消数据分组

如果你已经熟悉上面的项目符号,并且只想快速回答以下问题:你只想知道如何对标签执行聚合,但你很困惑,因为你的数据在单独的表中。在执行聚合之前,将|> group() 应用到你的Flux查询中来取消数据分组。如果你仍然困惑,请继续阅读。

使用示例数据探索Flux

开始使用InfluxDB最简单的方法是选择一个示例数据并将其用Flux写入InfluxDB。今天我们将使用NOAA水样数据。这个数据集相当大,所以我们将实际将数据写入我们的InfluxDB实例。为了写入数据,我们首先创建一个存储示例数据的目标桶。您可以使用InfluxDB UI 创建新桶或使用API 创建新桶

InfluxDB UI中“加载数据”页面的截图<figcaption>InfluxDB UI中“加载数据”页面的截图.</figcaption>

点击菜单右侧的“数据”。然后导航到“桶”选项卡。最后,点击“+创建桶”来创建您的桶并命名它。今天我们将命名为“noaa”。

根据示例数据文档,我们将复制并粘贴以下Flux代码到InfluxDB UI中的“脚本编辑器”

import "experimental/csv"

relativeToNow = (tables=<-) =>
  tables
    |> elapsed()
    |> sort(columns: ["_time"], desc: true)
    |> cumulativeSum(columns: ["elapsed"])
    |> map(fn: (r) => ({ r with _time: time(v: int(v: now()) - (r.elapsed * 1000000000))}))

csv.from(url: "https://influx-testdata.s3.amazonaws.com/noaa.csv")
  |> relativeToNow()
  |> to(bucket: "noaa", org: "example-org")

InfluxDB UI中“脚本编辑器”的截图 <figcaption>InfluxDB UI中“脚本编辑器”的截图.</figcaption>

点击“查询构建器”按钮返回查询构建器。点击“提交”按钮可以运行Flux查询。

在本TL;DR中,忽略大部分Flux。我们只需要理解的是,你需要编辑最后一行中的to()函数

  • 将桶参数替换为目标桶的名称。
  • 将org参数替换为您的组织名称。在InfluxDB Cloud中,您的组织是您注册账户时使用的电子邮件。

分组键及其如何确定你的带注释CSV输出中的表数量

Data Explorer - Query Builder

使用查询构建器从santa_monica和coyote_creek获取平均温度数据。切换到查看原始数据(橙色),可以看到注释CSV和组键。当列中的值都相同(绿色高亮显示)或不同(粉色)时,列分配组键注释值为true(此处以绿色突出显示)或false(粉色)。

查询一些数据,并将查看原始数据切换到“开”,以返回注释CSV输出。注释CSV输出是一系列表。组键定义了表的大小和数量。组键注释是一个布尔值,用于确定列中的值是否在每一行中都相同。具有值为true的组键注释的列是组的一部分。

在上面的图片中,我们查询了两个地点的平均温度数据。具体来说,我们查询了

  • 1个测量值,“average_temperature”。
  • 1个字段,“degree”
  • 2个“location”标签值,“coyote_creek”和“santa_monica”

这转换为以下通过脚本编辑器查看的Flux代码。

from(bucket: "noaa")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "average_temperature")
|> filter(fn: (r) => r["_field"] == "degrees")
|> filter(fn: (r) => r["location"] == "coyote_creek" or r["location"] == "santa_monica")
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> yield(name: "mean")

我们的注释CSV输出列包括

  • 表:此列将数值分配给表流中的表,其顺序与返回的顺序相同。由于我们查询了两个标签值,“coyote_creek”和“santa_monica”,我们将返回两个表。
  • _measurement:查询的数据的测量值——“average_temperature”
  • _field:查询的数据的字段键——“degrees”
  • _value:数据的字段值
  • _start:查询的起始日期
  • _stop:查询的结束日期
  • _time:时间序列的时间戳
  • location:查询的标签键

在这些列名下面是组键子标题。当一个列中的每一行都相同的时候,该列就是组键的一部分。组键中的列给出“GROUP”子标题,而组键之外的列给出“NO GROUP”子标题。

默认情况下,InfluxDB将以下列包含为组键的一部分

  • _measurement
  • _field
  • _start
  • _stop:查询的结束日期
  • 任何标签键列

这些列默认包含在组键中,以便为每个时间序列输出一个表。一个系列由测量值、标签集和字段键的唯一组合定义。UI将每个表作为单独的线条进行绘图。

现在想象一下,您想要找到两个地点上所有值的总和,因此添加了以下求和函数

from(bucket: "noaa")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "average_temperature")
|> filter(fn: (r) => r["_field"] == "degrees")
|> filter(fn: (r) => r["location"] == "coyote_creek" or r["location"] == "santa_monica")
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
|> sum()

该查询将返回以下结果

query resultes

sum()函数应用于流中的每个表,因此我们得到每个地点的总和,而不是我们期望的结果:两个地点的总和。

为了纠正这一点,我们首先必须将流中的两个表合并为一个表。有几种方法可以实现这一目标,但最简单的方法是消除组键中的“location”列。应用一个空的group()函数,不向函数传递任何列,将有效地取消我们的数据分组。换句话说,以下Flux查询

from(bucket: "noaa")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "average_temperature")
|> filter(fn: (r) => r["_field"] == "degrees")
|> filter(fn: (r) => r["location"] == "coyote_creek" or r["location"] == "santa_monica")
|> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)
//limit is addded to visualize the results on one page
|> limit(n:3)
|> group()

产生以下注释CSV输出

Annotated CSV output

注意,我们的两个表合并成了一个表,并且没有列是组键的一部分。现在,如果我们将sum()添加到我们的Flux查询末尾,我们就可以实现我们的初始目标并获得总和

Data Explorer - total sum

结论

我希望这篇InfluxDB博客文章能帮助缓解一些关于

  1. 注释CSV是什么
  2. 组键如何影响表流输出
  3. 那么如何取消数据的分组以便在流中对字段、标签和表格进行聚合呢?

如果您正在使用InfluxDB v2并需要帮助,请在我们的社区网站Slack频道中寻求帮助。如果您正在开发酷炫的物联网应用或在InfluxDB上监控您的应用,我们非常乐意了解相关信息,因此请确保分享您的经历!此外,请将您的想法、关注点或问题留在评论部分。我们非常希望得到您的反馈,并帮助您解决遇到的问题!

进一步阅读

尽管本文旨在提供一个全面概述,介绍如何在字段、标签或表流中进行聚合;以下资源可能也会对您有所帮助。

  1. TL;DR InfluxDB 技术提示 – 如何解释带注释的CSV:本文介绍了如何解释带注释的CSV,这是InfluxDB的Flux查询结果格式。
  2. Python和InfluxDB v2.0入门:本文介绍了如何开始使用Python客户端库。
  3. InfluxDB和Pandas入门:本文分享了如何开始使用Pandas将数据框写入InfluxDB,并使用Flux查询返回数据框。
  4. Flux初学者的五大挑战及学习使用Flux的资源:本文描述了Flux初学者常见的挑战,以及如何通过使用InfluxDB UI、理解带注释的CSV等方式来克服这些挑战。
  5. 中级Flux用户的五大挑战及优化Flux的资源:本文描述了中级和高级Flux用户常见的挑战,并提供了更多关于pushdown模式、Flux引擎如何工作等方面的详细信息。