Understand the Mapping Root

Documents in a pipeline can be hierarchical, which means an object can contain other objects or arrays, which themselves can contain objects or arrays.  For example, the following JSON document is hierarchical because the root object contains an object in the "child" field:

{ "name": "Acme", "child": { "field1": 1, "field2": 2 } }

Mapping simple hierarchical documents containing other objects is straightforward because you can directly map one field to another. However, mapping for documents that contain arrays of objects is complicated because the objects in the array must be mapped separately from the parent object. The mapping is separate because there is no unambiguous way to describe the array mapping with the expression language and JSONPaths. To map arrays, the Mapping Root property is in the Mapper Snap. 

The Mapping Root property is a JSONPath that limits the scope of a mapping to the parts of the document that match the specific path. For example, the Mapping Root $.my_array[*] enables the Mapper to iterate over the objects in the array and transform each object based on the mapping. The other parts of the document that do not match the Mapping Root pass through untouched in the output. The root is set to $, the document's root by default. 

To move variables inside $original to the root level, you must map the variables to root variables. For example, you must map $original.salary to $salary and $original.balance to $balance.

Because you must do array mappings separately, add an additional Mapper Snap for each array mapping. Chain additional Mapper Snaps together so the top levels of the hierarchy are mapped before they descend to the lower levels. This order is because the Mapper UI passes down the Input and Target schema views to show the fields in the array's objects.

The outer structures of the document must agree between the source and target. Otherwise, the schema views are not useful. 

The following example shows a pipeline that maps the source document to a target document:

Source document:

{ "name": "Acme", "employee": [ { "first_name": "Bob", "last_name": "Smith", "age": 32 }, { "first_name": "Joe", "last_name": "Doe", "age": 44 } ] }

Target document:

{ "company_name": "Acme", "workers": [ { "name": "Bob Smith", "age": 32 }, { "name": "Joe Doe", "age": 44 } ] }


The source document is hierarchical because it contains an array of objects. You need two Mapper Snaps:

  1. to map the parent fields

  2. to map the elements in the "employee" array. 

The first Mapper's configuration is simple because it only changes names:  

Source

Target

Source

Target

$name

$company_name

$employee

$workers

The second Mapper is connected to the output of the first mapper so that it works on the lower levels of the document hierarchy. You must change the "Mapping Root" for the Snap so the mapping transformations impact only the objects in the "workers" array. After setting the root, the Input schema only shows the fields in the array objects. If a target schema is available, it is narrowed down to show the "name" and "age" fields.  

Mapping Root: $workers[*]

Source

Target

Source

Target

$first_name + " " + $last_name

$name

$age

$age