# How to Use JSONata for Real-Time Data Transformation in Qubitro

This guide explains how to use JSONata expressions in Qubitro Transformation Functions to manipulate and structure real-time data before it is stored or used for automated actions.&#x20;

JSONata provides a flexible, lightweight way to filter, calculate, and restructure data without writing traditional code.

A few things to remember:

{% hint style="info" %}
Data can be modified **on-the-fly** before storage and automation.
{% endhint %}

{% hint style="info" %}
TF applies immediately to incoming data, whether raw or already decoded.
{% endhint %}

### How Transformation Functions Work in Qubitro

Once a device sends data, TF automatically applies the JSONata expression configured by the user.

If a Decoder Function exists, it will process raw data first, and then TF will apply JSONata expressions on the decoded output. If there is no decoder, TF will apply transformations directly to the published data.

{% @mermaid/diagram content="graph LR;
A\[Device Publishes Data] --> B{Is a Decoder Function Defined?};

B -- Yes --> C\[\[Decoder Function Processes Data]];
B -- No --> D\[(Pass Raw Data Directly)];

C -->|Decoded Data| E{{Apply JSONata in Transformation Function}};
D -->|Raw Data| E;

E -->|Transformed Data| F\[Store Processed Data];
E -->|Transformed Data| G\[Send Data to Rule Queue];

%% Minimal Color Styles
style A fill:#d9d9d9,stroke:#000,color:#000;
style C fill:#f2f2f2,stroke:#000,color:#000;
style E fill:#e0e0e0,stroke:#000,color:#000;" fullWidth="false" %}

### Basic JSONata Syntax

Here are some core **JSONata** concepts:

* **Mathematical functions:** *$sum(values)*, *$average(values)*, *$max(values)*, *$min(values)*.
* **Ternary operators:** condition ? trueValue : falseValue.
* **String and numeric literals:** "text" for strings, 42 for numbers.
* U**sing the root object:** $ refers to the root JSON object.
* **Accessing fields:** fieldname retrieves a specific property.

## Practical Implementations

### Example 1: Flattening Nested JSON

Convert a multi-level JSON object into a flat structure for better Qubitro compatibility.

{% stepper %}
{% step %}

### Incoming Data:

```json
{
  "sensor": {
    "type": "temperature",
    "readings": {
      "current": 22,
      "average": 21
    }
  }
}
```

{% endstep %}

{% step %}
**JSONata** **Expression**:

```json
{
  "sensor_type": sensor.type,
  "current_temperature": sensor.readings.current,
  "average_temperature": sensor.readings.average
}
```

{% endstep %}

{% step %}
**Transformed** **Data**:

```json
{
  "sensor_type": "temperature",
  "current_temperature": 22,
  "average_temperature": 21
}
```

{% endstep %}
{% endstepper %}

### Example 2: Extracting Values from Arrays

Transform an array of objects into structured key-value pairs.

{% stepper %}
{% step %}

### Incoming Data:

```json
{
  "sensors": [
    {"type": "temperature", "value": 22},
    {"type": "humidity", "value": 55}
  ]
}
```

{% endstep %}

{% step %}
**JSONata** **Expression**:

```json
{
  "temperature_value": sensors[type='temperature'].value,
  "humidity_value": sensors[type='humidity'].value
}
```

{% endstep %}

{% step %}
**Transformed** **Data**:

```json
{
  "temperature_value": 22,
  "humidity_value": 55
}
```

{% endstep %}
{% endstepper %}

### Example 3: Performing Mathematical Calculations

Use JSONata to compute sums, averages, and find min/max values dynamically.

{% stepper %}
{% step %}

### Incoming Data:

```json
{
  "values": [5, 10, 15, 20, 25]
}
```

{% endstep %}

{% step %}
**JSONata** **Expression**:

```json
{
  "sum": $sum(values),
  "average": $average(values),
  "max": $max(values),
  "min": $min(values)
}
```

{% endstep %}

{% step %}
**Transformed** **Data**:

```json
{
  "sum": 75,
  "average": 15,
  "max": 25,
  "min": 5
}
```

{% endstep %}
{% endstepper %}

### Example 4: Time Formatting and Duration Calculation

Modify timestamps into human-readable formats or compute durations.

{% stepper %}
{% step %}

### Incoming Data:

```json
{
  "event": {
    "start_time": "2020-01-01T08:00:00Z",
    "end_time": "2020-01-01T12:00:00Z"
  }
}
```

{% endstep %}

{% step %}
**JSONata** **Expression**:

```json
{
  "start_date": $fromMillis($toMillis(event.start_time), '[Y0001]-[M01]-[D01]'),
  "end_date": $fromMillis($toMillis(event.end_time), '[Y0001]-[M01]-[D01]'),
  "duration_hours": ($toMillis(event.end_time) - $toMillis(event.start_time)) / (1000*60*60) & " hours"
}
```

{% endstep %}

{% step %}
**Transformed** **Data**:

```json
{
  "start_date": "2020-01-01",
  "end_date": "2020-01-01",
  "duration_hours": "4 hours"
}
```

{% endstep %}
{% endstepper %}

### Example 5: Dynamically Accessing Data Using *$lookup()*

This method is useful when field names may change dynamically.

{% stepper %}
{% step %}

### Incoming Data:

```json
{
  "sensorData": {
    "temperature": 22,
    "humidity": 78
  }
}
```

{% endstep %}

{% step %}
**JSONata** **Expression**:

```json
{
  "temp_value": $lookup(sensorData, 'temperature'),
  "humidity_value": $lookup(sensorData, 'humidity')
}
```

{% endstep %}

{% step %}
**Transformed** **Data**:

```json
{
  "temp_value": 22,
  "humidity_value": 78
}
```

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.qubitro.com/guides/functions-and-data-processing/how-to-use-jsonata-for-real-time-data-transformation-in-qubitro.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
