1

TL;DR 私は Influxdb v2.0 を使用しており、(GUI のように) Influx クエリ構文を使用しています。デジタル 0/1 状態の複数のシリーズ (同じ _field、異なるタグ) があり、それらを合計したいと考えています。問題は、状態が不規則な時間間隔でデータベースに保存されることです。つまり、各タグの実際の実際の値は、可能な限り最後のポイントでいつでも照会する必要があります。関数として「last」を使用してaggregateWindowを試しましたが、最後に、ポイントが保存されていないウィンドウのテーブルをドロップするだけです。とにかくそれらを要約できるものはありますか?どのような方法でも構いません (データのエクスポートや、lmao の代わりに他の言語のスクリプトを使用するなど)。前もって感謝します。


シナリオ

私のチームは、以前に現実世界のイベントの各人を表す電話番号を使用してチェックイン/チェックアウト システムを実装し、InfluxDB v2.0 をデータベースとして使用することにしました (Grafana を介して簡単に監視できるように選択しました)。 . チェックイン/チェックアウト値のポイントを格納するバケットがあり、すべて同じスキーマです。スキーマは次のとおりです。

measurement: 'user'
tags: [phone, type]     // type is either ['normal', 'staff']
value: 0 or 1           // 0 for checking out event, 1 for checking in event

誰かがイベントをチェックインするたびに、値 1 のポイントが挿入されます。逆に、誰かがイベントをチェックアウトするたびに、値 0 のポイントが挿入されます。ユーザーが以前にチェックインしたように API を再度トリガーして再度チェックインした場合、ポイントが重複する可能性があることに注意してください (ただし、これは同じ状態の 1 と見なされます)。したがって、データはデジタルの 0/1 状態に似ていますが、ポイントの時間間隔が不規則で、電話番号ごとに 1 つのグラフ ラインがあります。同じ電話番号でも種類が違うと、私たちにとっては別人に見えます。

プロジェクトはすでに展開されており、データの後処理を行う必要があります。問題は、全期間のイベント内人口のグラフを視覚化することです。数学的な観点では、これは各人の状態 (0/1 ライン) を経時的に合計することで簡単に解決できるはずです。Influx クエリで最初に次のようなことを試しました。

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> group(columns: ["type"])
  |> aggregateWindow(every: v.windowPeriod, fn: sum, createEmpty: true)
  |> yield()

結果は非常に有望に見えます.2色の法線とスタッフの人口グラフです. しかし、よく見ると、Influx の sum 関数は、実際には各ウィンドウの各ポイントの _value を合計しています。つまり、ポイントのないウィンドウの場合、合計関数は実際にはデータベース内のすべての人を合計しません。目標は、ポイントのないウィンドウの実際の _value を合計することです (これらのウィンドウの _value は、最後のポイントの _value と同じにする必要があります。たとえば、午後 7 時にチェックインした場合、_value はすべて 1 にする必要があります7.00pm以降の時間でも、ウィンドウによっては意味がありません)。次に、次のようなことを試しました。

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: true)
  |> fill(usePrevious: true)
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1m, fn: sum)
  |> yield()

各ウィンドウに最後のポイントを使用し、ウィンドウを空の _value で前の可能なポイントで埋めてから、各ウィンドウの _value を再度合計します。しかし、その後、関数が実際に空のテーブルをドロップすることがわかりました。つまりlast、ポイントのないウィンドウがドロップされます (createEmpty は役に立たない)。last問題は、空のテーブルを削除せずに関数を見つける必要があることです。reduceのような独自のロジックを作成しようとしましlastたが、残念ながら思い通りにはなりませんでした (コーディングが間違っていた可能性があります)。

お気づきの点がございましたら、お助けください。どうもありがとうございました。

4

1 に答える 1

3

Nvm、私は解決策を見つけました。これは同じ状況にある人のためのものですが、パフォーマンスはあまりエレガントではありませんが、それが機能することがわかった唯一のクエリです。

from(bucket: "event_name")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "user")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: false)
  |> aggregateWindow(every: 1m, fn: mean, createEmpty: true)
  |> fill(usePrevious: true)
  |> fill(value: 0.0)
  |> group(columns: ["type"])
  |> aggregateWindow(every: 1m, fn: sum, createEmpty: false)
  |> yield(name: "population")
  1. last各ウィンドウの最新の状態を取得するために最初に使用します(ただし、last実際には空のテーブルをドロップするため、作成してcreateEmpty: trueも役に立ちません)
  2. 次に、ポイントを持たないウィンドウの場合、空のウィンドウに null でポイントを作成するためにmeanwithを使用します。実際に実際のポイントを持つウィンドウの場合、以前に使用したため、ウィンドウごとに 1 つのポイントしかないため、値を変更しないでください。ここで使用するポイントは、空のウィンドウにヌル ポイントを作成することです。ここでのステ​​ップは、 によって作成された空のテーブルを削除しない何もしない関数を見つけることです。参考までに、 andのような独自のカスタム関数を作成するなど、多くの関数を試しましたが、空のテーブルをドロップします (null の割り当ても許可されていません) 。そうcreateEmpty: true_valuemeanlastmeancreateEmptyreducemapfn: (tables=<-, x) => tablesaggregateWindowmeanここで私の最善の策ですが、副作用は私の値がintからfloatに変わることです。
  3. fillここでは、null ポイントを最後のウィンドウの値に置き換えるために使用します。これが、最後のステップから空のウィンドウのポイントに null を割り当てようとしている理由であり、meanこれしかできません。2 番目fillは、0 状態を表す初期の空のウィンドウ用です。
  4. 次にgroup、タイプとsumそれらを組み合わせることで、私が探している結果が得られるはずです

将来、私と同じような状況にある誰かを助けることができれば幸いです

于 2020-11-08T13:49:22.557 に答える