Joiners

Joiners are components of graph that join data from all connected input ports based on defined key and propagate the result to output port.



Transformations

In either of these components, you must define some transformation using the transform() function. In addition to this required function, you can define other two functions: init() and finished(). If you want to declare and initialize some variables, if you want to anything what should be done at the beginning of data processing by the component, you should do it within the init() function. If you want to free memory, delete some temporary files, you should define it within the finished() function. Either of these functions is called only once. The init() function is called at the beginning, the finished() function is called at the end. Unlike them, the required transform() function is called many times. It is called after init() and before finished(). All joiners implement a RecordTransform interface or inherit from a DataRecordTransform class.

Common attributes



Attribute Description Exp.
id component identification string
type component type. This attribute is automatically generated from gui. string


AproxMergeJoin

Joins records on port 0 (Master records) with records on port 1 (Slave records). Joining is based on specified key fields and their similarity - with defined maximum disimilarity/distance - computed as edit distance - “Levenshtein distance”

Input ports: * 0 - driver records

  • 1 - slave records

Output ports:

  • 0 - joined records with conformity greater then given limit. If in output metadada there are fields called “_total_conformity_” or “_keyName_conformity_”, where keyName is one of field's names from joinKey parameter, to these fields will be assigned computed conformity. These fields have to be of type “numeric”
  • 1 - joined records with conformity smaller then given limit but with the same matching key. Output metadata can have additional fields (see above)
  • 2 - (optional) driver records for which there is not matching slave
  • 3 - (optional) slave records for which there is not matching driver


Xml attributes:

Attribute Mandatory Description Default ETL Version since
id yes component identification
type yes component type APROX_MERGE_JOIN
joinKey yes field names with number of letters, weight and strength of comparison as four boolean values for each comparison level separated by :;| {colon, semicolon, pipe}. General form: fieldName maxNumberOfLetterstoChange fieldWeight identicalComparison tertiaryComparison secondaryComparison primaryComparison. Since ver. 2.5 it is advocated to use new firm syntax: $masterField=$slaveField(maxNumberOfLetterstoChange fieldWeight identicalComparison tertiaryComparison secondaryComparison primaryComparison). Conformity between two strings equals zero if transformation of one string to another necessitates more then maxNumberOfLetterstoChange letters to change. Weight of each field difference is counted due to following algorithm: weight given by user divided by sum of weights given by user.
matchingKey yes field name for comparing driver and slave records. Since ver. 2.5 it is advocated to use new firm syntax: $masterField=$slaveField.
transformClass if no transform name of the class to be used for transforming joined data which has conformity greater then conformity limit.If no class name is specified then it is expected that the transformation Java source code is embedded in XML
transform if no transformClass contains definition of transformation for joined records which has conformity greater then conformity limit in internal clover format
transformURL no contains path to the file with transformation code.
charset no encoding of extern source ISO-8859-1
transformClassForSuspicious if no transform
ForSuspicious
name of the class to be used for transforming joined data which has conformity smaller then conformity limit.If no class name is specified then it is expected that the transformation Java source code is embedded in XML
transformForSuspicious if no transformClass
ForSuspicious
contains definition of transformation for joined records which has conformi ty smaller then conformity limit in internal clover format
transformURLForSuspicious no contains path to the file with transformation code.
slaveOverrideKey no
since ver. 2.5 deprecated
can be used to specify different key field names for records on slave input; field names separated by :;| {colon, semicolon, pipe}
slaveMatchingOverride no
since ver. 2.5 deprecated
can be used to specify different key field name for records on slave input
conformity no joined records are divided to two sets depending on their computed conformity is greater or smaller then this parameter 0.75
errorActions no defines if graph is to stop, when transformation returns negative value. Available actions are: STOP or CONTINUE. For CONTINUE action, error message is logged to console or file (if errorLog attribute is specified) and for STOP there is thrown TransformExceptions and graph execution is stopped. Error action can be set for each negative value (value1=action1;value2=action2;…) or for all values the same action (STOP or CONTINUE). It is possible to define error actions for some negative values and for all other values (MIN_INT=myAction). -1=CONTINUE;MIN_INT=STOP 2.6
errorLog no path to the error log file. 2.6

joinKey - comparison strength:

  • identical - letters equals if they are identical
  • tertiary - comparison does not depend on upper or lower case
  • secondary - diacritic letters and theirs latin equivalents are equals
  • primary - letters with additional features (e.g.:penduncle, pick, circle) and theirs latin equivalents are equals


Example:

  <Node id="APROX_MERGE_JOIN0" type="APROX_MERGE_JOIN">
    <attr name="matchingKey">key</attr>
    <attr name="transform">${out.0.lname} = ${in.0.lname};
          ${out.0.fname} = ${in.0.fname};
          ${out.0.birthdate} = ${in.0.birthdate};
          ${out.0.gender} = ${in.0.gender};
          ${out.0.first_name} = ${in.1.first_name};
          ${out.0.last_name} = ${in.1.last_name};
          ${out.0.birth_date} = ${in.1.birth_date};
          ${out.0.gender1} = ${in.1.gender};
    </attr>
    <attr name="conformity">0.8</attr>
    <attr name="slaveOverrideKey">last_name;first_name</attr>
    <attr name="joinKey">lname 2 0.75 false true true true;fname 4 0.25 false false false true</attr>
    <attr name="transformForSuspicious">${out.1.lname} = ${in.0.lname};
          ${out.1.fname} = ${in.0.fname};
          ${out.1.first_name} = ${in.1.first_name};
          ${out.1.last_name} = ${in.1.last_name};
    </attr>
  </Node>
 
  <Node conformity="0.81" id="APROX_MERGE_JOIN1" 
        joinKey="$fname=$first_name(3 0.8 true false false false);$lname=$last_name(4 0.2 true false false false);" 
        matchingKey="$key=$key;#" transformClass="customizedTransformExample" type="APROX_MERGE_JOIN">
       <attr name="transformForSuspicious"><![CDATA[${out.0.lname} = ${in.0.lname};
           ${out.0.fname} = ${in.0.fname};
           ${out.0.birthdate} = ${in.0.birthdate};
           ${out.0.gender} = ${in.0.gender};
           ${out.0.first_name} = ${in.1.first_name};
           ${out.0.last_name} = ${in.1.last_name};
           ${out.0.birth_date} = ${in.1.birth_date};
           ${out.0.gender1} = ${in.1.gender};]]></attr>
  </Node>



DBJoin

Joins records from input port and database based on specified key. It expects that on port [0], there is a driver and from database is a slave. For each driver record, slave record is looked up in database. Pair of driver and slave records is sent to transformation class. The method transform is called for every pair of driver&slave. It skips driver records for which there is no corresponding slave (if there is connected output port 1, thees records are sent to it) - unless outer join (leftOuterJoin option) is specified, when only driver record is passed to transform method (no records is sent to output port 1).

Input ports: * one input port defined/connected.

Output ports:

  • [0] - joined records
  • [1] - (optional) skipped driver records


Xml attributes:

Attribute Mandatory Description Default ETL Version since
id yes component identification
type yes component type DBJOIN
dbConnection yes id of the Database Connection object to be used to access the database
sqlQuery yes query to be sent to database
joinKey yes field names separated by [:;|]
transformClass no name of the class to be used for transforming joined data.
transform no contains definition of transformation in internal clover format or as java code
transformURL no contains path to the file with transformation code. If not transformClass, nor transform, nor transformURL is not specified only records from database are sent to output port.
charset no encoding of extern source ISO-8859-1
metadata no metadata for data from database. If is not specified it can be obtained from sql query attribute.
leftOuterJoin no if left outer join has be performed false
maxCached no number of sets of records with different key which will be stored in memory 100
errorActions no defines if graph is to stop, when transformation returns negative value. Available actions are: STOP or CONTINUE. For CONTINUE action, error message is logged to console or file (if errorLog attribute is specified) and for STOP there is thrown TransformExceptions and graph execution is stopped. Error action can be set for each negative value (value1=action1;value2=action2;…) or for all values the same action (STOP or CONTINUE). It is possible to define error actions for some negative values and for all other values (MIN_INT=myAction). -1=CONTINUE;MIN_INT=STOP 2.6
errorLog no path to the error log file. 2.6

Example:

  <Node id="dbjoin0" type="DBJOIN">
        <attr name="metadata">Metadata3</attr>
        <attr name="transformClass">TransformTransformdbjoin0</attr>
        <attr name="sqlQuery">select * from employee where Employee_ID=?</attr>
        <attr name="joinKey">EmployeeID</attr>
        <attr name="dbConnection">DBConnection0</attr>
  </Node>



HashJoin (Ext)

Joins two records from two different input flows based on specified key. The flow on port 0 is the driver, the flow on port 1 is the slave. First, all records from slave flow are read and stored in hash table. Then for every record from driver flow, corresponding record from slave flow is looked up (if it exists)

Description:

Joins records on input ports. It expects driver stream at port [0] and slave streams at other input ports. Slave streams are expected to be small enough to store all the slave records in hashtable.
Each driver record is joined with corresponding slave records according to join keys specification.

  • For each driver record, slave records are looked up in Hashtables which are created from all records on slave inputs.
  • Tuple of driver and slave records is sent to transformation class.
  • The method transform is called for every tuple of driver and corresponding slaves.


There are three join modes available: inner, left outer, full outer.

  • Inner mode processess only driver records for which all associated slaves are available.
  • Left outer mode furthermore processes driver records with missing slaves.
  • Full outer mode additionally calls transformation method for slaves without driver.


In case you use outer mode, till 2.4 version be sure your transformation code is able to handle null input records. From 2.5 version it doesn't happen any more, because for lacking record there is used special null record - all getValue methods returns null instead of throwing exception. If you want to realise some action for such record you can compare it with NullRecord.NULL_RECORD (see example below). Hash join does not require input data to be sorted. But it spends some time at the beginning initializing hashtable of slave records. It is generally good idea to specify how many records are expected to be stored in each hashtable (there is one hashtable per each slave input), especially when you expect the number to be really great. It is better to specify slightly greater number to ensure that rehashing won't occure. For small record sets - up to 512 records, there is no need to specify the size.

Input ports: * 0 - driver record input.

  • 1..n - slave record inputs.

Output ports:

  • one output port defined/connected.


Xml attributes:

Attribute Mandatory Description Default ETL Version since
id yes component identification
type yes component type EXT_HASH_JOIN
joinKey yes join key specification in format mapping1#mapping2…, where mapping has format driver_field1=slave_field1| driver_field2=slave_field2| Since 2.5 version it is advocated to precede clover fields name by '$'. In case slave_field is missing it is supposed to be the same as the driver_field. When driver_field is missing (ie there's nothin before '='), it will be taken from the first mapping. Order of mappings corresponds to order of slave input ports. In case a mapping is empty or missing for some slave, the component will use first mapping instead of it.
transformClass if no transform name of the class to be used for transforming joined data. If no class name is specified then it is expected that the transformation Java source code is embedded in XML
transform if no transformClass contains definition of transformation
transformURL no contains path to the file with transformation code.
charset no encoding of extern source ISO-8859-1
joinType no inner/leftOuter/fullOuter Specifies type of join operation. inner
hashTableSize no how many records are expected (roughly) to be in hashtable. 512
slaveDuplicates no true/false - allow records on slave port with duplicate keys. False - multiple duplicate records are discarded - only the first one is used for join. false
errorActions no defines if graph is to stop, when transformation returns negative value. Available actions are: STOP or CONTINUE. For CONTINUE action, error message is logged to console or file (if errorLog attribute is specified) and for STOP there is thrown TransformExceptions and graph execution is stopped. Error action can be set for each negative value (value1=action1;value2=action2;…) or for all values the same action (STOP or CONTINUE). It is possible to define error actions for some negative values and for all other values (MIN_INT=myAction). -1=CONTINUE;MIN_INT=STOP 2.6
errorLog no path to the error log file. 2.6

Example:

  <Node id="JOIN" type="EXT_HASH_JOIN" joinKey="CustomerID" transformClass="org.jetel.test.reformatOrders"/>
 
  <Node id="JOIN" type="EXT_HASH_JOIN" joinKey="EmployeeID" joinType="inner">
        <attr name="transform">//#TL
              function transform(){
                 $OrderID := $OrderID;
                 $CustomerID := $CustomerID;
                 $EmployeeID := $EmployeeID;
                 $EmployeeID2 := num2str($1.EmployeeID);
                 $LastName := concat($1.LastName,":",$1.FirstName);
              }
        </attr>
  </Node>
 
 In-line transformation for 2.4 and lower ver.:
 <Node id="JOIN" type="EXT_HASH_JOIN" joinKey="EmployeeID=EmployeeID#CustomerID=CUSTOMERID" joinType="leftOuter">
        <attr name="transform">
 
            import org.jetel.component.DataRecordTransform;
            import org.jetel.data.*;
 
            public class reformatJoinTest extends DataRecordTransform{
 
                public boolean transform(DataRecord[] source, DataRecord[] target){
                    if (source[0] != null) {
                        target[0].getField(0).setValue(source[0].getField(0).getValue());	// OrderID
                        target[0].getField(1).setValue(source[0].getField(1).getValue());	// CustomerID
                        target[0].getField(2).setValue(source[0].getField(2).getValue());	// EmployeeID
                    } else {
                        target[0].getField(1).setValue("*MISSING*");
                    }
                    if (source[1]!=null){
                        target[0].getField(4).setValue(source[1].getField(1) + ", " + source[1].getField(2));	// Name
                    } else {
                        target[0].getField(4).setValue("*MISSING*");
                    }
                    if (source[2]!=null){
                        target[0].getField(3).setValue(source[2].getField(1).getValue());	// Company
                    } else {
                        target[0].getField(3).setValue("*MISSING*");
                    }
                    target[0].getField(5).setValue("*MISSING*");
                    return true;
                }
            }
        </attr>
  </Node>
 
  In-line transformation since 2.5 ver.:
  <Node id="JOIN" type="EXT_HASH_JOIN" joinKey="$EmployeeID=$EmployeeID#$CustomerID=$CUSTOMERID" joinType="leftOuter">
        <attr name="transform">
            import org.jetel.component.DataRecordTransform;
            import org.jetel.data.*;
 
            public class reformatJoinTest extends DataRecordTransform{
 
                public boolean transform(DataRecord[] source, DataRecord[] target){
                    target[0].getField(0).setValue(source[0].getField(0).getValue());	// OrderID
                    target[0].getField(1).setValue(source[0].getField(1).getValue());	// CustomerID
                    target[0].getField(2).setValue(source[0].getField(2).getValue());	// EmployeeID
                    target[0].getField(3).setValue(source[2].getField(1).getValue());	// Company
                    target[0].getField(4).setValue(source[1].getField(1) + ", " + source[1].getField(2));	// Name
                     if (source[0] == NullRecord.NULL_RECORD){
                        target[0].getField(4).setValue("driver missing");
                     }
                     if (source[1] instanceof NullRecord.NULL_RECORD){
                        target[0].getField(4).setValue("1st slave missing");
                     }
                      if (source[2].equals(NullRecord.NULL_RECORD)){
                        target[0].getField(4).setValue("2nd slave missing");
                     }
                  return true;
                }
            }
        </attr>
  </Node>



LookupJoin

Joins records on input port and from lookup table. It expects that on port [0], there is a driver and from lookup table is a slave. For each driver record, slave record is looked up in lookup table. Pair of driver and slave records is sent to transformation class. The method transform is called for every pair of driver&slave. It skips driver records for which there is no corresponding slave (if there is connected output port 1, theese records are sent to it) - unless outer join (leftOuterJoin option) is specified, when only driver record is passed to transform method (no records is sent to output port 1).
Note: In transformation, records from lookup table are treated as records from 1st source, while records from input port are treated as 0th source (see example).

Input ports: * one input port defined/connected.

Output ports:

  • [0] - joined records
  • [1] - (optional) skipped driver records


Xml attributes:

Attribute Mandatory Description Default ETL Version since
id yes component identification
type yes component type LOOKUP_JOIN
joinKey yes field names separated by [:;|].
lookupTable yes name of lookup table where are slave records.
transform if no transformClass contains definition of transformation in internal clover format or as java code
transformClass if no transform name of the class to be used for transforming joined data. If no class name is specified then it is expected that the transformation. Java source code is embedded in XML
transformURL no contains path to the file with transformation code.
charset no encoding of extern source ISO-8859-1
leftOuterJoin no true/false false
freeLookupTable no idicates if close lookup table after finishing execute() method. All records, which are stored only in memory will be lost. false
errorActions no defines if graph is to stop, when transformation returns negative value. Available actions are: STOP or CONTINUE. For CONTINUE action, error message is logged to console or file (if errorLog attribute is specified) and for STOP there is thrown TransformExceptions and graph execution is stopped. Error action can be set for each negative value (value1=action1;value2=action2;…) or for all values the same action (STOP or CONTINUE). It is possible to define error actions for some negative values and for all other values (MIN_INT=myAction). -1=CONTINUE;MIN_INT=STOP 2.6
errorLog no path to the error log file. 2.6

Example:

  <Node id="JOIN" type="LOOKUP_JOIN">
       <attr name="lookupTable">LookupTable0</attr>
       <attr name="joinKey">EmployeeID</attr>
       <attr name="transform">//#TL
             function transform(){
                 $OrderID := $OrderID;
                 $CustomerID := $CustomerID;
                 $EmployeeID := $EmployeeID;
                 $EmployeeID2 := num2str($1.EmployeeID);
                 $LastName := concat($1.LastName,":",$1.FirstName);
              }
       </attr>
  </Node>
 
  In-line transformation for 2.4 ver. and lower:
  <Node id="JOIN" type="LOOKUP_JOIN">
       <attr name="lookupTable">LookupTable0</attr>
       <attr name="joinKey">EmployeeID</attr>
       <attr name="transform">
             import org.jetel.component.DataRecordTransform;
             import org.jetel.data.DataRecord;
             import org.jetel.data.RecordKey;
             import org.jetel.data.lookup.LookupTable;
             import org.jetel.exception.JetelException;
             import org.jetel.graph.TransformationGraph;
 
             public class reformatTest extends DataRecordTransform{
 
                 public boolean transform(DataRecord[] source, DataRecord[] target){
 
                     if (source[1]==null) return false; // skip this one
 
                     target[0].getField(0).setValue(source[0].getField(0).getValue());
                     target[0].getField(1).setValue(source[0].getField(1).getValue());
                     target[0].getField(2).setValue(source[0].getField(2).getValue());
                     target[0].getField(3).setValue(source[1].getField(0).getValue());
                     target[0].getField(4).setValue(source[1].getField(1).getValue());
 
                     return true;
                 }
             }
       </attr>
  </Node>
 
  In-line transformation since 2.5 ver.:
  <Node id="JOIN" type="LOOKUP_JOIN">
       <attr name="lookupTable">LookupTable0</attr>
       <attr name="joinKey">EmployeeID</attr>
       <attr name="transform">
             import org.jetel.component.DataRecordTransform;
             import org.jetel.data.DataRecord;
             import org.jetel.data.RecordKey;
             import org.jetel.data.lookup.LookupTable;
             import org.jetel.exception.JetelException;
             import org.jetel.graph.TransformationGraph;
 
             public class reformatTest extends DataRecordTransform{
 
                 public boolean transform(DataRecord[] source, DataRecord[] target){
 
                     if (source[1]==NullRecord.NULL_RECORD) {
                        errorMessage = "Slave record not found";
                     }
 
                     target[0].getField(0).setValue(source[0].getField(0).getValue());
                     target[0].getField(1).setValue(source[0].getField(1).getValue());
                     target[0].getField(2).setValue(source[0].getField(2).getValue());
                     target[0].getField(3).setValue(source[1].getField(0).getValue());
                     target[0].getField(4).setValue(source[1].getField(1).getValue());
 
                     return true;
                 }
             }
       </attr>
  </Node>



MergeJoin (Ext)

Joins sorted records on input ports. It expects driver stream at port [0] and slave streams at other input ports. Each driver record is joined with corresponding slave records according to join keys specification. The method transform is every composed of driver and corresponding slaves. There are three join modes available: inner, left outer, full outer.

Inner mode processess only driver records for which all associated slaves are available.
Left outer mode furthermore processes driver records with missing slaves.
Full outer mode additionally calls transformation method for slaves without driver.

In case you use outer mode, till 2.4 version be sure your transformation code is able to handle null input records. From 2.5 version it doesn't happen any more, because for lacking record there is used special null record - all getValue methods returns null instead of throwing exception. If you want to realise some action for such record you can compare it with NullRecord.NULL_RECORD (see example below).

Input ports: * 0 - sorted driver record input

  • 1..n - sorted slave record inputs

Output ports:

  • one output port defined/connected.


Xml attributes:

Attribute Mandatory Description Default ETL Version since
id yes component identification
type yes component type EXT_MERGE_JOIN
joinKey yes Join key formatted as masterKeyFields#slave1KeyFields#…#slaveNKeyFields where masterKeyFields or slave#KeyFields are sequences of master or slave field names separated by semicolon and preceded by a dollar sign: $fieldK;…;$fieldM. Since 2.5 version it is advocated to precede clover fields name by '$'. Order of slave key parts corresponds to the order of slave input ports.
transformClass if no transform name of the class to be used for transforming joined data. If no class name is specified then it is expected that the transformation Java source code is embedded in XML
transform if no transformClass contains definition of transformation
transformURL no contains path to the file with transformation code.
charset no encoding of extern source ISO-8859-1
joinType no inner/leftOuter/fullOuter Specifies type of join operation. inner
slaveDuplicates no true/false - allow records on slave port with duplicate keys. False - multiple duplicate records are discarded - only the last one is used for join. true
ascendingInputs no true/false - input is sorted in ascending/descending order, respectively. true
errorActions no defines if graph is to stop, when transformation returns negative value. Available actions are: STOP or CONTINUE. For CONTINUE action, error message is logged to console or file (if errorLog attribute is specified) and for STOP there is thrown TransformExceptions and graph execution is stopped. Error action can be set for each negative value (value1=action1;value2=action2;…) or for all values the same action (STOP or CONTINUE). It is possible to define error actions for some negative values and for all other values (MIN_INT=myAction). -1=CONTINUE;MIN_INT=STOP 2.6
errorLog no path to the error log file. 2.6

Example:

  <Node id="JOIN" type="EXT_MERGE_JOIN" joinKey="CustomerID" transformClass="org.jetel.test.reformatOrders"/>
 
  <Node id="JOIN"
        type="EXT_MERGE_JOIN" 
        joinKey="EmployeeID=SlaveID;EmployeeType=SlaveType#EmployeeID=SlaveID;EmployeeType=SlaveType2" 
        joinType="inner">
        <attr name="transform">
              function transform() {
                 ${out.0.car} = ${in.0.car};
                 ${out.0.seqKey} = ${in.0.seqKey};
                 ${out.0.mobilephone} = ${in.0.mobilephone};
                 ${out.0.financial_bonus} = ((${in.1.monthly_bonus})*12)+(${in.1.yearly_bonus})
              }
        </attr>
  </Node>
 
  In-line transformation for 2.4 and lower ver.:
  <Node id="JOIN" type="EXT_MERGE_JOIN" joinKey="EmployeeID;EmployeeType" leftOuterJoin="true">
        <attr name="transform">
            import org.jetel.component.DataRecordTransform;
            import org.jetel.data.*;
 
            public class reformatJoinTest extends DataRecordTransform{
 
                int recNo = 0;
 
                public boolean transform(DataRecord[] source, DataRecord[] target){
 
                    target[0].getField(0).setValue(source[0].getField(0).getValue());
                    target[0].getField(1).setValue(source[0].getField(1).getValue());
                    target[0].getField(2).setValue(source[0].getField(2).getValue());
                    if (source[1]!=null){
                        target[0].getField(3).setValue(source[1].getField(0).getValue());
                        target[0].getField(4).setValue(source[1].getField(1).getValue());
                    }else{
			System.out.println("Slave record not found for " + recNo + "th record.");
                    }
                    recNo++;
                    return true;
                }
            }
        </attr>
  </Node>
 
  In-line transformation since 2.5 ver.:
  <Node id="JOIN" type="EXT_MERGE_JOIN" joinKey="$EmployeeID;$EmployeeType" leftOuterJoin="true">
        <attr name="transform">
            import org.jetel.component.DataRecordTransform;
            import org.jetel.data.*;
 
            public class reformatJoinTest extends DataRecordTransform{
 
                int recNo = 0;
 
                public boolean transform(DataRecord[] source, DataRecord[] target){
 
		    if (source[1] == NullRecord.NULL_RECORD) {
			System.out.println("Slave record not found for " + recNo + "th record.");
		    }
                    target[0].getField(0).setValue(source[0].getField(0).getValue());
                    target[0].getField(1).setValue(source[0].getField(1).getValue());
                    target[0].getField(2).setValue(source[0].getField(2).getValue());
                    target[0].getField(3).setValue(source[1].getField(0).getValue());
                    target[0].getField(4).setValue(source[1].getField(1).getValue());
                    recNo++;
                    return true;
                }
            }
        </attr>
  </Node>



RelationalJoin

COMMERCIAL, since version 2.8

Joins data records that are not equal with respect to a given join key and operator.

The RelationalJoin component has two input ports. The first one is referred to as the master port, the second one is referred to as the slave port. Each data record from the master port is joined with corresponding data records from the slave port. Data records to be joined are specified by a join key and a relational operator. Any of the following relational operators may be used: !=, <, <=, >, >=. The < operator for example means that each data record from the master port is joined with all data records from the slave port that are lexicographically greater.

Data records coming through the master port are processed one by one. On the other hand, data records coming through the slave port need to be buffered. In the worst case, all the slave data records need to be buffered. Thus the number of data records on the slave port should be as small as possible.

All data records coming through connected input ports have to be sorted in the following way:

Operator(s) Required sort order of input data records
!= Data records DO NOT NEED to be sorted on either of the input ports.
<, <= Data records have to be sorted in the DESCENDING ORDER on both input ports.
>, >= Data records have to be sorted in the ASCENDING ORDER on both input ports.

In case the ordering is incorrect, execution of the component fails.


Input ports: * 0 – master record input

  • 1 – slave record input


Output ports:

  • one output port defined/connected


XML attributes:

Attribute Mandatory Description Default
id yes Identification of the component. N/A
type yes The type of the component (has to be RELATIONAL_JOIN). N/A
transform yes/no Join transform as a Java or CTL source code. null
transformUrl yes/no URL of an external Java/CTL source code of the join transform. null
transformUrlCharset no Character set used in the source code of the join transform specified via an URL. ISO-8859-1
transformClassName yes/no Class name of a Java class implementing the join transform. null
joinKey yes Join key formatted as masterKeyFields#slaveKeyFields where masterKeyFields or slaveKeyFields are sequences of master or slave field names separated by semicolon and preceded by a dollar sign: $fieldK;…;$fieldM. N/A
joinOperator yes Relational operator used for data record comparison. Any of the !=, <, <=, >, >= operators may be used. N/A
joinType no Type of join. One of INNER, LEFT_OUTER join types may be used. INNER


components/joiners.txt · Last modified: 2010/02/05 08:53 by newacct
Back to top
chimeric.de = chi`s home Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0