首页

Query using conditional logic

Flux provides if, then, and else conditional expressions that allow for powerful and flexible Flux queries.

Conditional expression syntax
// Pattern
if <condition> then <action> else <alternative-action>

// Example
if color == "green" then "008000" else "ffffff"

Conditional expressions are most useful in the following contexts:

  • When defining variables.
  • When using functions that operate on a single row at a time ( filter(), map(), reduce() ).

Evaluating conditional expressions

Flux evaluates statements in order and stops evaluating once a condition matches.

For example, given the following statement:

if r._value > 95.0000001 and r._value <= 100.0 then "critical"
else if r._value > 85.0000001 and r._value <= 95.0 then "warning"
else if r._value > 70.0000001 and r._value <= 85.0 then "high"
else "normal"

When r._value is 96, the output is “critical” and the remaining conditions are not evaluated.

Examples

Conditionally set the value of a variable

The following example sets the overdue variable based on the dueDate variable’s relation to now().

dueDate = 2019-05-01
overdue = if dueDate < now() then true else false

Create conditional filters

The following example uses an example metric variable to change how the query filters data. metric has three possible values:

  • Memory
  • CPU
  • Disk
metric = "Memory"

from(bucket: "telegraf/autogen")
  |> range(start: -1h)
  |> filter(fn: (r) =>
      if v.metric == "Memory"
        then r._measurement == "mem" and r._field == "used_percent"
      else if v.metric == "CPU"
        then r._measurement == "cpu" and r._field == "usage_user"
      else if v.metric == "Disk"
        then r._measurement == "disk" and r._field == "used_percent"
      else r._measurement != ""
  )

Conditionally transform column values with map()

The following example uses the map() function to conditionally transform column values. It sets the level column to a specific string based on _value column.

from(bucket: "telegraf/autogen")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent" )
  |> map(fn: (r) => ({
    r with
    level:
      if r._value >= 95.0000001 and r._value <= 100.0 then "critical"
      else if r._value >= 85.0000001 and r._value <= 95.0 then "warning"
      else if r._value >= 70.0000001 and r._value <= 85.0 then "high"
      else "normal"
    })
  )
from(bucket: "telegraf/autogen")
  |> range(start: -5m)
  |> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent" )
  |> map(fn: (r) => ({
    // Retain all existing columns in the mapped row
    r with
    // Set the level column value based on the _value column
    level:
      if r._value >= 95.0000001 and r._value <= 100.0 then "critical"
      else if r._value >= 85.0000001 and r._value <= 95.0 then "warning"
      else if r._value >= 70.0000001 and r._value <= 85.0 then "high"
      else "normal"
    })
  )

Conditionally increment a count with reduce()

The following example uses the aggregateWindow() and reduce() functions to count the number of records in every five minute window that exceed a defined threshold.

threshold = 65.0

from(bucket: "telegraf/autogen")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent" )
  |> aggregateWindow(
      every: 5m,
      fn: (column, tables=<-) => tables |> reduce(
            identity: {above_threshold_count: 0.0},
            fn: (r, accumulator) => ({
              above_threshold_count:
                if r._value >= threshold then accumulator.above_threshold_count + 1.0
                else accumulator.above_threshold_count + 0.0
            })
        )
    )
threshold = 65.0

from(bucket: "telegraf/autogen")
  |> range(start: -1h)
  |> filter(fn: (r) => r._measurement == "mem" and r._field == "used_percent" )
  // Aggregate data into 5 minute windows using a custom reduce() function
  |> aggregateWindow(
      every: 5m,
      // Use a custom function in the fn parameter.
      // The aggregateWindow fn parameter requires 'column' and 'tables' parameters.
      fn: (column, tables=<-) => tables |> reduce(
            identity: {above_threshold_count: 0.0},
            fn: (r, accumulator) => ({
              // Conditionally increment above_threshold_count if
              // r.value exceeds the threshold
              above_threshold_count:
                if r._value >= threshold then accumulator.above_threshold_count + 1.0
                else accumulator.above_threshold_count + 0.0
            })
        )
    )

InfluxDB OSS 2.0 release candidate

InfluxDB OSS v2.0.rc includes breaking changes that require a manual upgrade from all alpha and beta versions. For information, see:

Upgrade to InfluxDB OSS v2.0.rc