Dynamically Selecting Time Ranges in InfluxDB Flux Queries: Error and Solutions

I’m using InfluxDB to store time-series data and Flux for querying. I have a scenario where I need to dynamically select start and end times based on specific conditions for each sensor and motif. However, it seems that Flux doesn’t support dynamic variables in the way I’m trying to use them. The start_time and end_time variables are calculated independently and not passed dynamically into the range() function. I’m encountering an error where the start_time and end_time variables are not recognized as time values by the range() function, resulting in the following error: “error calling function ‘range’ @18:6-18:46: value is not a time, got stream[t84]”. I’m seeking suggestions or workarounds to resolve this issue and effectively query data with dynamically selected start and end times based on specific conditions. Below is the query and the error encountered:

Query:

start_time = from(bucket: "motifs_timestamp")
  |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
  |> filter(fn: (r) => r["timestamp"] == "start")
  |> map(fn: (r) => ({
      _time: r._time
  }))
  

end_time = from(bucket: "motifs_timestamp")
  |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
  |> filter(fn: (r) => r["timestamp"] == "end")
  |> map(fn: (r) => ({
      _time: r._time
  }))


from(bucket: "motifs_timestamp")
  |> range(start: start_time, stop: end_time)
  |> filter(fn: (r) => r["_measurement"] == "motifs_per_signal")
  |> filter(fn: (r) => r["_field"] == "sensor_reading")
  |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
  |> filter(fn: (r) => r["motif_name"] == "Motifs_1")

Error:
“error calling function ‘range’ @18:6-18:46: value is not a time, got stream[t84]”

Any insights or assistance would be greatly appreciated. Thank you!

@Madhurima_Rawat The problem here is that your start_time and end_time variables currently return streams of tables, not time values. You need to extract a scalar time value out of each stream. You can use findRecord() to do this. In the example below, I structured start_time and end_time as functions that return a single time value. Also, from() requires a range() with it, so those functions include a range() call that queries data since the Unix epoch.

start_time = () => {
    timeRecord = from(bucket: "motifs_timestamp")
        |> range(start: 0)
        |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
        |> filter(fn: (r) => r["timestamp"] == "start")
        |> findRecord(fn: (key) => true, idx: 0)
    
    return timeRecord._time
}

end_time = () => {
    timeRecord = from(bucket: "motifs_timestamp")
        |> range(start: 0)
        |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
        |> filter(fn: (r) => r["timestamp"] == "end")
        |> map(fn: (r) => ({_time: r._time}))
        |> findRecord(fn: (key) => true, idx: 0)

    return timeRecord._time
}

from(bucket: "motifs_timestamp")
    |> range(start: start_time(), stop: end_time())
    |> filter(fn: (r) => r["_measurement"] == "motifs_per_signal")
    |> filter(fn: (r) => r["_field"] == "sensor_reading")
    |> filter(fn: (r) => r["sensor_name"] == "[3:25]")
    |> filter(fn: (r) => r["motif_name"] == "Motifs_1")

Thank you for your assistance and prompt response. I’m pleased to inform you that the query provided worked perfectly after making the adjustments you suggested. Your guidance in structuring the start_time and end_time functions to return single time values using findRecord() was particularly helpful.

I appreciate your support in resolving this issue, and I’m grateful for your expertise. If I encounter any further challenges or require additional assistance, I won’t hesitate to reach out.

Once again, thank you for your help.

Best regards,

Madhurima Rawat