Query to generate windowed aggregates with timestamp at window start and without partial data (updated for 2023)

In this post @alex88 helpfully showed a solution to aggregating data while ensuring that no partial windows are included in the aggregation (and also to have the window timestamps be the start of the windows instead of the end of the windows). That solution used some features that were experimental at the time (3.5 years ago!) but there are non-experimental options today.

The updated version of that solution is:

import "date"

from(bucket: "bucket")
  |> range(start: date.truncate(t: -15m, unit: 5m))
  |> filter(fn: (r) =>
    r._measurement == "metric"
    and r.machine == "83"
    and (r._field == "temp_1")
  |> aggregateWindow(every: 5m, fn: mean, timeSrc: "_start")

Just like the original solution, this one takes the current time, winds it back 15 minutes, and then further winds it back to the nearest ‘5 minute’ boundary. The non-experimental version of date.truncate makes this trivial to do since it accepts a duration as the starting point (which is then applied to the result of now()).