Version

    Mapping

    Mapping is a part of each transformation defined in some of the CloverDX components.

    Calculated or generated values or values of input fields are assigned (mapped) to output fields.

    1. Mapping assigns a value to an output field.

    2. Mapping operator is the following:

      =

    3. Mapping must always be defined inside a function.

    4. Mapping may be defined in any place inside a function.

      [Important]Important

      In CTL2, mapping may be in any place of the transformation code and may be followed by any code. This is one of the differences between the two versions of CloverDX Transformation Language.

      (In CTL1, mapping had to be at the end of the function and could only be followed by one return statement.)

      In CTL2, mapping operator is simply the equal sign.

    5. Remember that you can also wrap a mapping in a user-defined function which would be subsequently used inside another function.

    6. You can also map different input metadata to different output metadata by field names or by field positions. See examples below.

    Mapping of Different Metadata (by Name)

    When you map input to output like this:

    $out.0.* = $in.0.*;

    input metadata may even differ from those on the output.

    In the expression above, fields of the input are mapped to the fields of the output that have the same name and type as those of the input. The order in which they are contained in respective metadata and the number of all fields in either metadata is not important.

    When you have input metadata in which the first two fields are firstname and lastname, each of these two fields is mapped to its counterpart on the output. Such output firstname field may even be the fifth and lastname field be the third, but those two fields of the input will be mapped to these two output fields.

    Even if both input metadata and output metadata had more fields, such fields would not be mapped to each other if an output field did not exist with the same name as one of the input (independently on the mutual position of the fields in corresponding metadata).

    In addition to the simple mapping as shown above ($out.0.* = $in.0.*;), you can also use the following function:

    void copyByName(record to, record from);

    Example 65.22. Mapping of Metadata by Name (using the copyByName() function)

    recordName2 myOutputRecord;
    copyByName(myOutputRecord.*,$in.0.*);
    $in.0.* = myOutputRecord.*;

    [Important]Important

    Metadata fields are mapped from input to output by name and data type independently on their order and on the number of all fields.

    Following syntax may also be used: myOutputRecord.copyByName($in.0.*);

    Mapping of Different Metadata (by Position)

    Sometimes you need to map input to output, but names of input fields are different from those of output fields. In such a case, you can map input to output by position.

    To achieve this, you must use the following function:

    void copyByPosition(record to, record from);

    Example 65.23. Mapping of Metadata by Position

    recordName2 myOutputRecord;
    copyByPosition(myOutputRecord,$in.0.*);
    $out.0.* = myOutputRecord.*;

    [Important]Important

    Metadata fields may be mapped from input to output by position (as shown in the example above).

    Following syntax may also be used: myOutputRecord.copyByPosition($in.0.*);

    Use Case 1 - One String Field to Upper Case

    To show in more details how mapping works, we provide here a few examples of mappings.

    We have a graph with the Reformat component. Metadata on its input and output are identical. First two fields (field1 and field2) are of string data type, the third (field3) is of integer data type.

    1. We want to change the letters of field1 values to upper case while passing the other two fields unchanged to the output.

    2. We also want to distribute records according to the value of field3. Those records in which the value of field3 is less than 5 should be sent to the output port 0, the others to the output port 1.

    Examples of Mapping

    As the first possibility, we have the mapping for both ports and all fields defined inside the transform() function of CTL template.

    Example 65.24. Example of Mapping with Individual Fields

    Note that the mappings will be performed for all records. In other words, even when the record goes to the output port 1, the mapping for output port 0 will be performed, and vice versa.

    Moreover, mapping consists of individual fields, which may be complex in case there are many fields in a record. In the next examples, we will see how this can be solved in a better way.

    function integer transform() {
    
        // mapping input port records to output port records
        // each field is mapped separately
        $out.0.field1 = upperCase($in.0.field1);
        $out.0.field2 = $in.0.field2;
        $out.0.field3 = $in.0.field3;
        $out.1.field1 = upperCase($in.0.field1);
        $out.1.field2 = $in.0.field2;
        $out.1.field3 = $in.0.field3;
    
        // output port number returned
        if ($out.0.field3 < 5) return 0; else return 1;

    [Note]Note

    As CTL2 allows to use any code after the mapping, here we have used the if statement with two return statements after the mapping.

    In CTL2, mapping may be in any place of the transformation code and may be followed by any code.

    As the second possibility, we also have the mapping for both ports and all fields defined inside the transform() function of CTL template. But now there are wild cards used in the mapping. These pass the records unchanged to the outputs and, after this wildcard mapping, the fields that should be changed are specified.

    Example 65.25. Example of Mapping with Wild Cards

    Note that mappings will be performed for all records. In other words, even when the record goes to the output port 1, the mapping for output port 0 will be performed, and vice versa.

    However, now the mapping uses wild cards at first, which passes the records unchanged to the output, but the first field is changed below the mapping with wild cards.

    This is useful when there are many unchanged fields and a few that will be changed.

    function integer transform() {
    
        // mapping input port records to output port records
        // wild cards for mapping unchanged records
         // transformed records mapped additionally
         $out.0.* = $in.0.*;
         $out.0.field1 = upperCase($in.0.field1);
         $out.1.* = $in.0.*;
         $out.1.field1 = upperCase($in.0.field1);
    
         // return the number of output port
         if ($out.0.field3 < 5) return 0; else return 1;

    [Note]Note

    As CTL2 allows to use any code after the mapping, here we have used the if statement with two return statements after the mapping.

    In CTL2, mapping may be in any place of the transformation code and may be followed by any code.

    As the third possibility, we have the mapping for both ports and all fields defined outside the transform() function of CTL template. Each output port has its own mapping.

    Wild cards are used here as well.

    The mapping that is defined in a separate function for each output port allows the following improvements:

    • Mapping is performed only for a respective output port. In other words, now there is no need to map the record to the port 1 when it will go to the port 0, and vice versa.

    Example 65.26. Example of Mapping with Wild Cards in Separate User-Defined Functions

    Moreover, mapping uses wild cards at first, which pass the records unchanged to the output. The first field is changed below the mapping with wild card. This is useful when there are many unchanged fields and a few that will be changed.

    // mapping input port records to output port records
        // inside separate functions
        // wild cards for mapping unchanged records
        // transformed records mapped additionally
        function void mapToPort0 () {
            $out.0.* = $in.0.*;
            $out.0.field1 = upperCase($in.0.field1);
        }
    
        function void mapToPort1 () {
            $out.1.* = $in.0.*;
            $out.1.field1 = upperCase($in.0.field1);
        }
    
        // use mapping functions for all ports in the if statement
        function integer transform() {
            if ($in.0.field3 < 5) {
                mapToPort0(); 
                return 0;
            }
            else {
                mapToPort1();
                return 1;
            }