在Influx中查询特定键的最新时间戳(MAX/Last)

Jul*_*iën 8 influxdb

使用InfluxDB(v1.1),我有一个要求,我想获得特定密钥的最后一个入口时间戳.无论存储哪个测量值,无论这个值是多少.

设置很简单,在这里我有三个测量:location,networkusage.
只有一个关键:device_id.

在伪代码中,这将是这样的:

# notice the lack of a FROM clause on measurement here...
SELECT MAX(time) WHERE 'device_id' = 'x';
Run Code Online (Sandbox Code Playgroud)

问题:查询这个问题最有效的方法是什么?

我想要这个的原因是会有一个分散的同步过程.某些设备可能在过去一小时内已更新,而其他设备未在几个月内更新.能够为设备(密钥)获得明确的"最后更新"时间戳将允许我更有效地将新点存储到Influx.

我也注意到有关InfluxDB的GitHub仓库(#5793)的类似讨论,但问题是没有任何字段/密钥过滤.这正是我想要的:获取特定密钥的"最后"条目.

Mic*_*esa 11

不幸的是,不会有单一的查询,可以让你找到你想要的.你必须在客户端做一些工作.

您想要的查询是

SELECT last(<field name>), time FROM <measurement> WHERE device_id = 'x'
Run Code Online (Sandbox Code Playgroud)

您需要为每个测量运行此查询.

SELECT last(<field name>), time FROM location WHERE device_id = 'x'
SELECT last(<field name>), time FROM network WHERE device_id = 'x'
SELECT last(<field name>), time FROM usage WHERE device_id = 'x'
Run Code Online (Sandbox Code Playgroud)

从那里你将得到一个时间戳最大的那个

> select last(value), time from location where device_id = 'x'; select last(value), time from network where device_id = 'x'; select last(value),     time from usage where device_id = 'x';
name: location
time                last
----                ----
1483640697584904775 3

name: network
time                last
----                ----
1483640714335794796 4

name: usage
time                last
----                ----
1483640783941353064 4
Run Code Online (Sandbox Code Playgroud)


Leo*_*evi 11

tl;博士; 第一个()最后()如果测量有多个字段,字段中NULL值的选择器将不工作始终。最有效的解决方案是使用这些查询

第一的:

SELECT * FROM <measurement> [WHERE <tag>=value] LIMIT 1
Run Code Online (Sandbox Code Playgroud)

最后的:

SELECT * FROM <measurement> [WHERE <tag>=value] ORDER BY time DESC LIMIT 1
Run Code Online (Sandbox Code Playgroud)

解释:

如果您的测量中只有一个字段,那么建议的解决方案将起作用,但如果您有多个字段并且值可以为 NULL,则first()last()选择器将无法一致地工作,并且可能会返回不同的时间戳每个领域。例如,假设您有以下数据集:

time                   fieldKey_1     fieldKey_2     device
------------------------------------------------------------
2019-09-16T00:00:01Z   NULL           A              1
2019-09-16T00:00:02Z   X              B              1
2019-09-16T00:00:03Z   Y              C              2
2019-09-16T00:00:04Z   Z              NULL           2
Run Code Online (Sandbox Code Playgroud)

在这种情况下查询

SELECT first(fieldKey_1) FROM <measurement> WHERE device = "1" 
Run Code Online (Sandbox Code Playgroud)

将返回

time                   fieldKey_1
---------------------------------
2019-09-16T00:00:02Z   X         
Run Code Online (Sandbox Code Playgroud)

并且对 first(fieldKey_2) 的相同查询将返回不同的时间

time                   fieldKey_2
---------------------------------
2019-09-16T00:00:01Z   A
Run Code Online (Sandbox Code Playgroud)

使用last查询时会发生类似的问题。

如果您想知道,它不会查询 'first(*)',因为您将在结果中获得 'epoch-0' 时间,例如:

 time                   first_fieldKey_1    first_fieldKey_2
 -------------------------------------------------------------
 1970-01-01T00:00:00Z   X                   A
Run Code Online (Sandbox Code Playgroud)

因此,解决方案将使用LIMITORDER BY 的组合进行查询。例如,对于第一次值,您可以使用:

SELECT * FROM <measurement> [WHERE <tag>=value] LIMIT 1
Run Code Online (Sandbox Code Playgroud)

对于最后一个你可以使用

SELECT * FROM <measurement> [WHERE <tag>=value] ORDER BY time DESC LIMIT 1
Run Code Online (Sandbox Code Playgroud)

它既安全又快速,因为它会根据索引进行中继。

奇怪的是,在开篇帖子中链接线程中提到了这种更简单的方法,但被丢弃了。也许这只是失去了忽视。

InfluxData 博客中有一个关于该主题的主题也建议使用这种方法。


小智 6

我尝试了一下,它在一个命令中对我有用:

SELECT last(<field name>), time FROM location, network, usage WHERE device_id = 'x'
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

name: location
time                last
----                ----
1483640697584904775 3

name: network
time                last
----                ----
1483640714335794796 4

name: usage
time                last
----                ----
1483640783941353064 4
Run Code Online (Sandbox Code Playgroud)