InfluxDB(v1.1)を使用して、特定のキーの最後のエントリのタイムスタンプを取得する必要があります。これが保存されている測定値に関係なく、これがどの値であったかに関係なく。
セットアップは簡単で、3つの測定値があります:location
、network
およびusage
。
キーは1つだけです:device_id
。
疑似コードでは、これは次のようになります。
# notice the lack of a FROM clause on measurement here...
SELECT MAX(time) WHERE 'device_id' = 'x';
質問:これを照会する最も効率的な方法は何でしょうか?
これが必要な理由は、分散型の同期プロセスがあるためです。過去1時間に更新されたデバイスと、数か月更新されていないデバイスがあります。デバイス(キー)の明確な「最終更新日」タイムスタンプを取得できると、Influxへの新しいポイントをより効率的に保存できます。
InfluxDBのGitHubリポジトリ(#5793) についても同様の議論があることに気づきましたが、質問はフィールド/キーによるフィルタリングではありません。そして、これがまさに私が欲しいものです。特定のキーの「最後の」エントリを取得します。
残念ながら、あなたが探しているものを取得する単一のクエリはありません。クライアント側で少し作業を行う必要があります。
必要なクエリは
SELECT last(<field name>), time FROM <measurement> WHERE device_id = 'x'
測定ごとにこのクエリを実行する必要があります。
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'
そこから、タイムスタンプが最大のものを取得します
> 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
私はこれを試しました、そしてそれは私のために単一のコマンドでうまくいきました:
SELECT last(<field name>), time FROM location, network, usage WHERE device_id = 'x'
私が得た結果:
name: location
time last
---- ----
1483640697584904775 3
name: network
time last
---- ----
1483640714335794796 4
name: usage
time last
---- ----
1483640783941353064 4
tl; dr;first()およびlast()測定に複数のフィールドがあり、フィールドにNULL値がある場合、セレクターは一貫して機能しません。最も効率的なソリューションは、これらのクエリを使用することです
最初:
SELECT * FROM <measurement> [WHERE <tag>=value] LIMIT 1
最終:
SELECT * FROM <measurement> [WHERE <tag>=value] ORDER BY time DESC LIMIT 1
説明:
測定に単一のフィールドがある場合、推奨される解決策が機能しますが、複数のフィールドがあり、値が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
この場合、クエリ
SELECT first(fieldKey_1) FROM <measurement> WHERE device = "1"
戻ります
time fieldKey_1
---------------------------------
2019-09-16T00:00:02Z X
そして、first(fieldKey_2)の同じクエリは異なる時間を返します
time fieldKey_2
---------------------------------
2019-09-16T00:00:01Z A
lastでクエリを実行すると、同様の問題が発生します。
疑問に思っている場合は、次のような結果で「Epoch-0」の時間を取得するため、「first(*)」のクエリは実行されません。
time first_fieldKey_1 first_fieldKey_2
-------------------------------------------------------------
1970-01-01T00:00:00Z X A
したがって、ソリューションは [〜#〜] limit [〜#〜] と ORDER BY の組み合わせを使用してクエリを実行することになります。たとえば、初めて使用できる値は次のとおりです。
SELECT * FROM <measurement> [WHERE <tag>=value] LIMIT 1
そして最後のものはあなたが使うことができます
SELECT * FROM <measurement> [WHERE <tag>=value] ORDER BY time DESC LIMIT 1
インデックスを中継するため、安全で高速です。
このより単純なアプローチは 開始ポストにリンクされたスレッド で言及されていたが、破棄されたことを言及するのは興味深いことです。見落とされただけかもしれません。
ここでは、件名について InfluxDataブログのスレッド もあり、このアプローチの使用を提案しています。