TigerData logo
TigerData logo
  • Product

    Product

    Tiger Cloud

    Robust elastic cloud platform for startups and enterprises

    TimescaleDB Enterprise

    Self-managed TimescaleDB for on-prem, edge and private cloud

    Open source

    TimescaleDB

    Time-series, real-time analytics and events on Postgres

    Search

    Vector and keyword search on Postgres

  • Industry

    Data Centers

    Energy & Utilities

    Oil & Gas Operations

    Smart Manufacturing

    Crypto

  • Docs
  • Pricing
  • Developer Hub

    Changelog

    Benchmarks

    Blog

    Community

    Customer Stories

    Events

    Support

    Integrations

    Launch Hub

  • Company

    About

    TigerData logo

    Timescale

    Partners

    Security

    Careers

Contact usStart a free trial
Tiger Data

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events

Products

  • TimescaleDB
  • Tiger Cloud
  • TimescaleDB Enterprise
  • Postgres Search Stack

Industry

  • Data Centers
  • Energy & Utilities
  • Oil & Gas Operations
  • Smart Manufacturing
  • Crypto

Support

  • Cloud Status
  • Support
  • Security
  • Terms of Service
  • Code Of Conduct

Learn

  • Documentation
  • Blog
  • Tutorials
  • Changelog
  • Success Stories

Company

  • About
  • Contact Us
  • Careers
  • Newsroom
  • Brand
  • Events
Privacy preferencesLegalPrivacySitemap

Subscribe to the Tiger Data newsletter

Gold Partner with Inductive Automation — Ignition

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Tiger Data
GOLD PARTNER WITHINDUCTIVE AUTOMATION

2026 (c) Timescale, Inc., d/b/a Tiger Data.
All rights reserved.

Privacy preferencesLegalPrivacySitemap

Adapting JSON Structures for Real-Time Aggregates: A Community Solution

J

Jônatas Davi Paganini

D

Dustin Sorensen

March 29th, 2024

4 min

Share

J

Jônatas Davi Paganini

D

Dustin Sorensen

March 29th, 2024

4 min

Share

Copy as HTML

Open in ChatGPT

Open in Claude

Open in v0

Continuous Aggregates

JSON

Tutorials

Table of contents

  1. 01 Aggregating JSONB and Array Columns—The Challenge
  2. 02 Custom Aggregate Functions for JSONB Values—The Community Solution
  3. 03 Join the Timescale Community
Get started for free
A handshake over a black backgrou: the solution for adapting JSON structures for real-time aggregates came from our community

When you’re handling large volumes of data and multiple aggregations simultaneously, having flexible and efficient data structures is key. In a recent chat in the Timescale Community Slack, Dustin Sorensen, technical lead at Energy Toolbase (and this post’s guest collaborator), shared how you can work with array or JSONB columns and real-time data aggregations. 

We’ll walk you through his clever solution for efficiently managing and aggregating data from multiple sensors or IoT devices without the need to create a dedicated column for each sensor. As a developer advocate and community manager, I (Jônatas) am often blown away by the level of comradery, support, and problem-solving focus displayed by our community—it’s an absolute joy to learn from this inspiring group of people. Feel free to join us on Slack if you’re a data geek yourself, or head to the Timescale Community page to learn more.

But now, back to JSON structures.

Aggregating JSONB and Array Columns—The Challenge

image

Community member Chintan Pathak recently posed a question in our Slack channel about JSON structures, namely the capability of Timescale's real-time continuous aggregates to work with array or JSONB columns.

For those unfamiliar with them, real-time continuous aggregates automatically refresh the aggregated data in the background to provide you with up-to-date, accurate results, almost like a supercharged version of PostgreSQL materialized views. (Not to toot our own horn, but we recently made these real-time aggregations faster, too.)

Chintan’s use case involved a variable number of sensors per system_id, with the need to aggregate individual sensor values currently stored in a JSONB column. The goal was to avoid the cumbersome process of creating a dedicated column for each sensor, which would require a separate table for each "system" with a different number of sensors.

Custom Aggregate Functions for JSONB Values—The Community Solution

To address this challenge, Dustin shared an innovative solution involving creating custom aggregate functions. These functions allow for the aggregation of any JSONB values, providing the flexibility to handle both numeric and non-numeric data within the same column. His approach eliminates the need for multiple columns for each data type, streamlining the data aggregation process.

So, here’s what he shared:

Custom functions for aggregating JSONB values

-- Aggregate an array of 'any' jsonb values CREATE OR REPLACE FUNCTION aggregate_jsonb_array(jsonb[]) RETURNS jsonb AS $$ DECLARE   jsonb_value jsonb;   agg_mode text;   agg_avg numeric; BEGIN   -- Use mode for non-numeric values   FOREACH jsonb_value IN ARRAY $1   LOOP       -- If there is even one non-numeric value, then treat the whole array as non-numeric       IF NOT jsonb_typeof(jsonb_value) IN ('number') THEN         -- Convert array to table in order to pass into mode() as an aggregated argument         SELECT             mode() WITHIN GROUP (ORDER BY value) FROM (SELECT trim('"' FROM value::text) AS value FROM unnest($1) AS value) AS values         INTO agg_mode;         RETURN to_jsonb(agg_mode);       END IF;   END LOOP;   -- Use average for numeric values   -- Convert array to table in order to pass into avg() as an aggregated argument   SELECT       avg(value::numeric) FROM (SELECT value FROM unnest($1) AS value) AS values   INTO agg_avg;   RETURN to_jsonb(agg_avg); END; $$ STRICT IMMUTABLE LANGUAGE plpgsql -- Custom aggregate for 'any' values stored as jsonb CREATE OR REPLACE AGGREGATE aggregate_all_types_jsonb(jsonb) (   sfunc = array_append,   stype = jsonb[],   combinefunc = array_cat,   finalfunc = aggregate_jsonb_array,   initcond = '{}' )

Example of an aggregate using custom functions

CREATE MATERIALIZED VIEW IF NOT EXISTS five_minute_aggregate WITH (timescaledb.continuous, timescaledb.materialized_only = FALSE) AS SELECT   time_bucket('5 minutes', time) AS time_bucket,   gateway,   channel,   aggregate_all_types_jsonb(data -> 'v') AS value FROM control_system_metrics GROUP BY time_bucket, gateway, channel WITH NO DATA
image

Join the Timescale Community

Dustin's solution is a practical approach to handling complex JSONB columns for real-time aggregation, catering to both average calculations for numbers and mode calculations for text. This flexibility showcases the power of TimescaleDB's extensibility and the innovative spirit of our community.

Our users are our most powerful driving force, and we will keep fostering community engagement and the exchange of ideas to overcome technical challenges. We want to be a part of the solution, helping developers build reliable, smart, and effective software applications.

Join the Timescale community to share insights, ask questions, and collaborate on solving complex data aggregation and management problems. Together, we can drive innovation and efficiency in database solutions. 🚀


Here’s the full conversation thread if you want to check it out.

// Related posts

Real-Time Analytics for Time Series: A Dev’s Intro to Continuous Aggregates
Real-Time Analytics for Time Series: A Dev’s Intro to Continuous Aggregates

TimescaleDB

Continuous Aggregates

Real-Time Analytics for Time Series: A Dev’s Intro to Continuous Aggregates

Continuous aggregates are high-performance PostgreSQL materialized views, boosting performance and enabling real-time analytics for time series in PostgreSQL.

By Sarah Conway

December 3rd, 2024

How We Made Real-Time Data Aggregation in Postgres Faster by 50,000%
How We Made Real-Time Data Aggregation in Postgres Faster by 50,000%

Engineering

PostgreSQL, Blog

How We Made Real-Time Data Aggregation in Postgres Faster by 50,000%

Learn how we accelerated real-time data aggregation in PostgreSQL by 50,000 % by tweaking the query planner.

By Fabrízio de Royes Mello

March 20th, 2024

Quickly Building SQL Dashboards for Time Series With Continuous Aggregates
Quickly Building SQL Dashboards for Time Series With Continuous Aggregates

Product & Engineering

Data Visualization

Quickly Building SQL Dashboards for Time Series With Continuous Aggregates

A tutorial on building dashboards for time-series data with continuous aggregates.

By Diana Hsieh

December 19th, 2023

Stay updated with new
posts and releases.

Receive the latest technical articles and release notes in your inbox.