Documentation

Query using conditional logic

See the equivalent InfluxDB v2.4 documentation: 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-01T00:00:00Z
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,
                }),
            ),
    )

Was this page helpful?

Thank you for your feedback!


Set your InfluxDB URL

Upgrade to InfluxDB Cloud or InfluxDB 2.0!

InfluxDB Cloud and InfluxDB OSS 2.0 ready for production.