Skip to content

Commit f60aa5f

Browse files
Merge pull request #897 from redis/DOC-4568-rdi-map-transform-example
DOC-4568 added map transform example page
2 parents 3c60f66 + ce99734 commit f60aa5f

File tree

1 file changed

+170
-0
lines changed
  • content/integrate/redis-data-integration/data-pipelines/transform-examples

1 file changed

+170
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
---
2+
Title: Restructure JSON or hash objects
3+
alwaysopen: false
4+
categories:
5+
- docs
6+
- integrate
7+
- rs
8+
- rdi
9+
description: null
10+
group: di
11+
linkTitle: Restructure objects
12+
summary: Redis Data Integration keeps Redis in sync with a primary database in near
13+
real time.
14+
type: integration
15+
weight: 40
16+
---
17+
18+
By default, RDI adds fields to
19+
[hash]({{< relref "/develop/data-types/hashes" >}}) or
20+
[JSON]({{< relref "/develop/data-types/json" >}}) objects in the target
21+
database that closely match the columns of the source table.
22+
The examples below show how you can create a completely new object structure
23+
from existing fields using the
24+
[`map`]({{< relref "/integrate/redis-data-integration/reference/data-transformation/map" >}})
25+
transformation.
26+
27+
## Map to a new JSON structure
28+
29+
The first
30+
[job file]({{< relref "/integrate/redis-data-integration/data-pipelines/data-pipelines#job-files" >}})
31+
example creates a new [JSON]({{< relref "/develop/data-types/json" >}})
32+
object structure to write to the target.
33+
The `source` section selects the `employee` table of the
34+
[`chinook`](https://github.com/Redislabs-Solution-Architects/rdi-quickstart-postgres)
35+
database (the optional `db` value here corresponds to the
36+
`sources.<source-name>.connection.database` value defined in
37+
[`config.yaml`]({{< relref "/integrate/redis-data-integration/data-pipelines/data-pipelines#the-configyaml-file" >}})).
38+
39+
In the `transform` section, the `map` transformation uses a [JMESPath](https://jmespath.org/)
40+
expression to specify the new JSON format. (Note that the vertical bar "|" in the `expression`
41+
line indicates that the following indented lines should be interpreted as a single string.)
42+
The expression resembles JSON notation but with data values supplied from
43+
table fields and
44+
[JMESPath functions]({{< relref "/integrate/redis-data-integration/reference/jmespath-custom-functions" >}}).
45+
46+
Here, we rename the
47+
`employeeid` field to `id` and create two nested objects for the `address`
48+
and `contact` information. The `name` field is the concatenation of the existing
49+
`firstname` and `lastname` fields, with `lastname` converted to uppercase.
50+
In the `contact` subobject, the `email` address is obfuscated slightly, using the
51+
`replace()` function to hide the '@' sign and dots.
52+
53+
In the `output` section of the job file, we specify that we want to write
54+
to a JSON object with a custom key. Note that in the `output` section, you must refer to
55+
fields defined in the `map` transformation, so we use the new name `id`
56+
for the key instead of `employeeid`.
57+
58+
The full example is shown below:
59+
60+
```yaml
61+
source:
62+
db: chinook
63+
table: employee
64+
transform:
65+
- uses: map
66+
with:
67+
expression: |
68+
{
69+
"id": employeeid,
70+
"name": concat([firstname, ' ', upper(lastname)]),
71+
"address": {
72+
"street": address,
73+
"city": city,
74+
"state": state,
75+
"postalCode": postalcode,
76+
"country": country
77+
},
78+
"contact": {
79+
"phone": phone,
80+
"safeEmail": replace(replace(email, '@', '_at_'), '.', '_dot_')
81+
}
82+
}
83+
language: jmespath
84+
output:
85+
- uses: redis.write
86+
with:
87+
connection: target
88+
data_type: json
89+
key:
90+
expression: concat(['emp:', id])
91+
language: jmespath
92+
```
93+
94+
If you query one of the new JSON objects, you see output like the following:
95+
96+
```bash
97+
> JSON.GET emp:1 $
98+
"[{\"id\":1,\"name\":\"Andrew ADAMS\",\"address\":{\"street\":\"11120 Jasper Ave NW\",\"city\":\"Edmonton\",\"state\":\"AB\",\"postalCode\":\"T5K 2N1\",\"country\":\"Canada\"},\"contact\":{\"phone\":\"+1 (780) 428-9482\",\"safeEmail\":\"andrew_at_chinookcorp_dot_com\"}}]"
99+
```
100+
101+
Formatted in the usual JSON style, the output looks like the sample below:
102+
103+
```json
104+
{
105+
"id": 1,
106+
"name": "Andrew ADAMS",
107+
"address": {
108+
"street": "11120 Jasper Ave NW",
109+
"city": "Edmonton",
110+
"state": "AB",
111+
"postalCode": "T5K 2N1",
112+
"country": "Canada"
113+
},
114+
"contact": {
115+
"phone": "+1 (780) 428-9482",
116+
"safeEmail": "andrew_at_chinookcorp_dot_com"
117+
}
118+
}
119+
```
120+
121+
## Map to a hash structure
122+
123+
This example creates a new [hash]({{< relref "/develop/data-types/hashes" >}})
124+
object structure for items from the `track` table. Here, the `map` transformation uses
125+
[SQL](https://en.wikipedia.org/wiki/SQL) for the expression because this is often
126+
more suitable for hashes or "flat"
127+
JSON objects without subobjects or arrays. The expression renames some of the fields.
128+
It also calculates more human-friendly representations for the track duration (originally
129+
stored in the `milliseconds` field) and the storage size (originally stored in the
130+
`bytes` field).
131+
132+
The full example is shown below:
133+
134+
```yaml
135+
source:
136+
db: chinook
137+
table: track
138+
transform:
139+
- uses: map
140+
with:
141+
expression:
142+
id: trackid
143+
name: name
144+
duration: concat(floor(milliseconds / 60000), ':', floor(mod(milliseconds / 1000, 60)))
145+
storagesize: concat(round(bytes / 1048576.0, 2), 'MB')
146+
language: sql
147+
output:
148+
- uses: redis.write
149+
with:
150+
connection: target
151+
data_type: hash
152+
key:
153+
expression: concat('track:', id)
154+
language: sql
155+
```
156+
157+
If you query the data for one of the `track` hash objects, you see output
158+
like the following:
159+
160+
```bash
161+
> hgetall track:16
162+
1) "id"
163+
2) "16"
164+
3) "name"
165+
4) "Dog Eat Dog"
166+
5) "duration"
167+
6) "3:35.0"
168+
7) "storagesize"
169+
8) "6.71MB"
170+
```

0 commit comments

Comments
 (0)