Interval and nearest match

It has lot of GROUPS and UNNEST as range of dates increases or interval decreases it take time.

Check is this what you are expecting and how it performs.

SELECT d.panelid, d.sensorid, MILLIS_TO_STR(iv) AS interval, MIN([ABS(STR_TO_MILLIS(el.timestamp)-iv),el])[1] AS el FROM (
       SELECT d.panelid, d.sensorid,
              ARRAY el FOR el IN d.data WHEN el.timestamp BETWEEN "2015-06-04T09:00:00" AND "2015-07-05T17:00:00" END AS data,
              ARRAY v FOR v IN ARRAY_RANGE(STR_TO_MILLIS("2015-06-04T09:00:00"),
                                           STR_TO_MILLIS("2015-07-05T17:00:00"),STR_TO_DURATION("12h")/1000000) END AS interval
            FROM `data` d WHERE d.panelid="a-si" AND d.sensorid="voc" AND d.date BETWEEN "2015-06-04" AND "2015-07-05") AS d
     UNNEST d.data AS el UNNEST d.interval AS iv
     GROUP BY d.panelid,d.sensorid, iv;

Seems to give me the same output, and it was a little faster at 48.95s

I think date comparison is too long that is why it takes time. You may have to revisit your query.
MIN calculation has whole data range. i.e. 30 days.
Sample document has data point for every 3 hours. i.e If you have guarantee the every 3 hours you can only keep few data points for each interval and see if that improves.