Search code examples
influxdbflux

Multiple operation on single column in Flux


Trying to recreate some of the basics in Flux compared to InfluxQL is quite a stretch at present.

I can’t work out how to ask for multiple projections.

select max(temp) - min(temp) from my_measurement

I’m not sure how to go about this in Flux.

Thanks


Solution

  • Option 1 - built in function

    The simplest way is probably to use the built-in spread function:

    The spread() function outputs the difference between the minimum and maximum values in a specified column.

    from(bucket: "example-bucket")
      |> range(start: -5m)
      |> filter(fn: (r) =>
        r._measurement == "cpu" and
        r._field == "usage_system"
      )
      |> spread()
    

    Option 2 - custom function

    If you want complete control over the logic, creating a custom aggregate function for this would work. Something along the lines of this (assuming your data has at least one positive value):

    delta = (tables=<-, outputField="delta") =>
      tables
        |> reduce(
          // Define the initial accumulator record
          identity: {
            maximum: 0.0,
            minimum: math.maxfloat,
            delta: 0.0
          },
          fn: (r, accumulator) => ({
            // update max and min on each reduce loop
            maximum: if r._value > accumulator.maximum then r._value else accumulator.maximum,
            minimum: if r._value < accumulator.minimum then r._value else accumulator.minimum,
            // take the delta
            delta: accumulator.maximum - accumulator.minimum
          })
        )
        // Set the _field label of the output table to to the value
        // provided in the outputField parameter
        |> set(key: "_field", value: outputField)
        // Rename delta column to _value
        |> rename(columns: {delta: "_value"})
        // Optionally, Drop the max and min columns since they are no longer needed
    //     |> drop(columns: ["maximum", "minimum"])
    
    
    // apply your custom function wherever you want to calculate a delta
    from(bucket: "my-bucket")
      |> range(start: -1h)
    // optionally filter here to isolate the field that you want 
    // |> filter(fn: (r) => <predicate>)
      |> delta()
    

    This would yield the delta between the max and min values from the last range worth of data (-1h in this example). Once you create the custom function, you can use it on any stream.