Using GenericTraversalMasterService

In this section:

GenericTraversalMasterService is the most powerful native RO service. It allows retrieving multiple entities connected by relations and traversing the data in the master model. For every master view (Mv), there is one service genericMvTraversal.

The basic use of the service is to retrieve one record from a master entity identified by ID or a combination of origin and sourceID.

There are two advanced features:


Top of page

x
Data Model

The following image shows the iWay MDS Master Data Layer model, followed by samples which are done using the Tutorial project, working with its data and model.

When traversing or preloading, use parent and child roles for relationship names instead of technical names of relationships (the Name field). For example:

<traverse relationshipName="addresses" /> or <rel name="addresses">

Parent/child roles are defined in the relationship configuration, as shown in the following image.

If you have no roles defined in relationships, you will have to use the value in the Name attribute (<name>) or rev_<name> for relationships going from a child to a parent. For example:

<traverse relationshipName="party_has_address" />

or

<traverse relationshipName="rev_party_has_address" />.

Top of page

x
Basic Usage

The simplest usage is similar to GetMasterByIdService, where you specify the entity name and record ID in the request (internal iWay MDS primary key):

<request>
	<startWith entity="party" id="38" />
</request>

The response contains a one-party record:

<list>
	<party>
		<metadata>
			<id>38</id>
			<active>true</active>
			<creationTid>1002</creationTid>
			<lastUpdateTid>1002</lastUpdateTid>
			<creationDate>2014-09-02T12:47:59+02:00</creationDate>
			<lastUpdateDate>2014-09-02T12:47:59+02:00</lastUpdateDate>
		</metadata>
		<attributes>
			<cmo_type>P</cmo_type>
			<cmo_first_name>Smith</cmo_first_name>
			<cmo_last_name>John</cmo_last_name>
			<cmo_gender>M</cmo_gender>
			<cmo_birth_date>1978-12-16T00:00:00+01:00</cmo_birth_date>
			<cmo_sin>095242434</cmo_sin>
		</attributes>
		<relationships/>
	</party>
</list>

The master record to retrieve is identified either by ID (as shown in the previous example) or by a combination of the instance record sourceId and origin:

<request>
		<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
</request>

NME will automatically find the instance record and its master record. The response will be the same.


Top of page

x
Simple Traversing

GenericTraversalMasterService allows traversing from the start point to other entities over relationships defined in the master model. For example, if you want to retrieve addresses related to a given party, use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<traversal>
		<traverse relationshipName="addresses" />
	</traversal>
</request>

The following response will be a list of addresses:

<list>
	<address>
		<metadata>
			...
		</metadata>
		<attributes>
			<party_master_id>38</party_master_id>
			<cmo_type>R</cmo_type>
			<cmo_street>13-3295 Sunnyside</cmo_street>
			<cmo_state>BC</cmo_state>
			<cmo_zip>V3H4Z4</cmo_zip>
		</attributes>
		<relationships/>
	</address>
	<address>
		<metadata>
			...
		</metadata>
		<attributes>
			<party_master_id>38</party_master_id>
			<cmo_type>M</cmo_type>
			<cmo_street>80 Hemlock Dr</cmo_street>
			<cmo_city>Anmore</cmo_city>
			<cmo_state>BC</cmo_state>
			<cmo_zip>V3H4W9</cmo_zip>
		</attributes>
		<relationships/>
	</address>
</list>


x
Traversing with a Simple Filter

Traversing over relationships can be enhanced by a filter. For example, if you want to see only addresses of type M, add a filter element with the eq subelement, as shown in the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<traversal>
		<traverse relationshipName="addresses">
			<filter>
				<eq attribute="cmo_type" value="M" />
			</filter>
		</traverse>
	</traversal>
</request>

The response will be only one address:

<list>
	<address>
		<metadata>
			...
		</metadata>
		<attributes>
			<party_master_id>38</party_master_id>
			<cmo_type>M</cmo_type>
			<cmo_street>80 Hemlock Dr</cmo_street>
			<cmo_city>Anmore</cmo_city>
			<cmo_state>BC</cmo_state>
			<cmo_zip>V3H4W9</cmo_zip>
		</attributes>
		<relationships/>
	</address>
</list>


x
Traversing With an Advanced Filter

Traversing filter can have more advanced conditions. For example, if you want only addresses that have good quality address instances, use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<traversal>
		<traverse relationshipName="addresses">
			<filter>
				<exists>
					<traverse relationshipName="instances">
<!-- virtual traverse to address_instance records -->
						<filter>
							<eq attribute="sco_address"value="0" /> <!-- good quality means score is 0 -->
						</filter>
					</traverse>
				</exists>
			</filter>
		</traverse>
	</traversal>
</request>

This request can be translated as the following:

This example shows that a filter defined by an exists condition can be recursive: depth is not limited. However, every step of recursion decreases performance of the service.

The filter element can contain multiple eq and exists sub-elements. Those are evaluated by default as AND, for example, all conditions must be met to return a record. You can change this to OR by setting up an operator attribute on the filter element, as shown in the following syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<traversal>
		<traverse relationshipName="addresses">
			<filter operator="OR">
				<eq attribute="cmo_type" value="M" />
				<eq attribute="cmo_type" value="R" />
			</filter>
		</traverse>
	</traversal>
</request>


x
Chained Traverse

Traversing over relationships can be chained. For instance, multiple traverse elements can define a long path from the starting point to the destination entity. For example, if you want to get all parties related to input party records, use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<traversal>
		<traverse relationshipName="relparent" /> <!-- traverse to
associative entity rel_party_party -->
		<traverse relationshipName="child" /> <!-- traverse
back to party -->
	</traversal>
</request>

Each traverse element can have its own complex filter as described above.


Top of page

x
Preloading of Related Records

The second advanced feature of GenericTraversalMasterService is the ability to return not only records of one entity, but related records as well. For example, if you want a party record with all addresses, use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<preloadedRelationships>
		<rel name="addresses" />
	</preloadedRelationships>
</request>

The response will be a complex hierarchical XML, as shown in the following syntax.

<list>
	<party>
		<metadata>
			...
		</metadata>
		<attributes> <!-- party record attributes -->
			<cmo_type>P</cmo_type>
			<cmo_first_name>Smith</cmo_first_name>
			<cmo_last_name>John</cmo_last_name>
			<cmo_gender>M</cmo_gender>
			<cmo_birth_date>1978-12-16T00:00:00+01:00</cmo_birth_date>
			<cmo_sin>095242434</cmo_sin>
		</attributes>
		<relationships>
		<addresses> <!-- address records -->
			<address>
				<metadata>
				...
				</metadata>
				<attributes>
					<party_master_id>38</party_master_id>
					<cmo_type>R</cmo_type>
					<cmo_street>13-3295 Sunnyside</cmo_street>
					<cmo_state>BC</cmo_state>
					<cmo_zip>V3H4Z4</cmo_zip>
				</attributes>
				<relationships/>
			</address>
			<address>
				<metadata>
				...
				</metadata>
				<attributes>
					<party_master_id>38</party_master_id>
					<cmo_type>M</cmo_type>
					<cmo_street>80 Hemlock Dr</cmo_street>
					<cmo_city>Anmore</cmo_city>
					<cmo_state>BC</cmo_state>
					<cmo_zip>V3H4W9</cmo_zip>
				</attributes>
				<relationships/>
				</address>
			</addresses>
		</relationships>
	</party>
</list>


x
Preloading of Related Records With a Filter

When preloading related records, you can apply a filter so that only some records are returned. For example, if you want a party record with all addresses of type M, use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<preloadedRelationships>
		<rel name="addresses">
			<filter>
				<eq attribute="cmo_type" value="M" />
			</filter>
		</rel>
	</preloadedRelationships>
</request>

The response will contain a party record with one address, as shown in the following syntax.

<list>
	<party>
		<metadata>
		...
		</metadata>
		<attributes>
			<cmo_type>P</cmo_type>
			<cmo_first_name>Smith</cmo_first_name>
			<cmo_last_name>John</cmo_last_name>
			<cmo_gender>M</cmo_gender>
			<cmo_birth_date>1978-12-16T00:00:00+01:00</cmo_birth_date>
			<cmo_sin>095242434</cmo_sin>
		</attributes>
		<relationships>
			<addresses>
				<address>
					<metadata>
						...
					</metadata>
					<attributes>
						<party_master_id>38</party_master_id>
						<cmo_type>M</cmo_type>
						<cmo_street>80 Hemlock Dr</cmo_street>
						<cmo_city>Anmore</cmo_city>
						<cmo_state>BC</cmo_state>
						<cmo_zip>V3H4W9</cmo_zip>
					</attributes>
					<relationships/>
				</address>
			</addresses>
		</relationships>
	</party>
</list>


x
Advanced Preloading of Related Records

There are several more possibilities:



x
Preloading Records Related Over Several Relationships

As an example, if you want to retrieve a party record with all related parties, you can use the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1002" />
	<preloadedRelationships>
		<rel name="relparent/child" />
	</preloadedRelationships>
</request>

Note the definition of preloadedRelationships relparent/child. If you want to preload records related over several relationships, you have to concatenate the names of relationships with the slash (/). This will force the service to jump over two relationships to get to records.

If you specify a filter for this preloaded relationship, it will be applied to records of the last entity, for example, party. If you want to specify a filter to be applied to the first entity (for example, associative entity rel_party_party in this example), you will have to add that entity to preloadedRelationships, as shown in the following request syntax:

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1018" />
	<preloadedRelationships>
		<rel name="relparent">
			<filter> <!-- filter on associative entity rel_party_party -->
				<eq attribute="cmo_p2p_rel_type" value="FAMILY" />
			</filter>
		</rel>
		<rel name="relparent/child">
			<filter> <!-- filter on related party entity -->
				<eq attribute="cmo_gender" value="M" />
			</filter>
		</rel>
	</preloadedRelationships>
</request>

The response will be a more complex hierarchical XML:

<list>
	<party>
		<metadata>
			...
		</metadata>
		<attributes>
<!-- party attributes -->
			<cmo_type>P</cmo_type>
			<cmo_first_name>Sandy</cmo_first_name>
			<cmo_last_name>Hettinger</cmo_last_name>
			<cmo_gender>F</cmo_gender>
			<cmo_birth_date>1965-09-21T00:00:00+01:00</cmo_birth_date>
			<cmo_sin>856527270</cmo_sin>
		</attributes>
		<relationships>
			<relparent>
				<rel_party_party>
					<metadata>
						...
					</metadata>
						<attributes> <!-- party2party relation attributes -->
						<parent_id>29</parent_id>
						<child_id>31</child_id>
<cmo_p2p_rel_type>FAMILY</cmo_p2p_rel_type>
					</attributes>
				<relationships>
					<child>
						<party>
							<metadata>
								...
						</metadata>
						<attributes>
<!-- attributes of related party -->
<cmo_type>P</cmo_type>
<cmo_first_name>Tom</cmo_first_name>
<cmo_last_name>Donathan</cmo_last_name>
<cmo_gender>M</cmo_gender>
<cmo_birth_date>1966-02-04T00:00:00+01:00</cmo_birth_date>
<cmo_sin>961085248</cmo_sin>
								</attributes>
								<relationships/>
							</party>
						</child>
					</relationships>
				</rel_party_party>
			</relparent>
		</relationships>
	</party>
</list>


x
Complex Example

The following example shows party sourceId as an input, with the following request:

"We want to email every man in Ohio this party is related to as family."

<request>
	<startWith entity="party" origin="crm#customer#party" sourceId="1018" />
	<traversal>
		<traverse relationshipName="relparent">
			<filter>
				<eq attribute="cmo_p2p_rel_type" value="FAMILY" />
			</filter>
		</traverse>
		<traverse relationshipName="child">
			<filter>
				<eq attribute="cmo_gender" value="M" />
				<exists>
					<traverse relationshipName="contacts">
						<filter>
							<eq attribute="cmo_type" value="email" />
							<exists>
								<traverse relationshipName="instances">
									<filter>
										<eq attribute="sco_value" value="0" />
									</filter></traverse>
								</exists>
							</filter>
						</traverse>
					</exists>
					<exists>
						<traverse relationshipName="addresses">
							<filter>
								<eq attrbitue="cmo_city" value="Anmore" />
							</filter>
						</traverse>
					</exists>
				</filter>
			</traverse>
		</traversal>
		<preloadedRelationships>
			<rel name="contacts">
				<filter>
					<eq attribute="cmo_type" value="email" />
					<exists>
						<traverse relationshipName="instances">
							<filter>
								<eq attribute="sco_value" value="0" />
							</filter>
						</traverse>
					</exists>
				</filter>
			</rel>
			<rel name="contacts/instances" />
			<rel name="addresses" />
		</preloadedRelationships>
	</request>

The service performs the following tasks:

You can see that GenericTraverseMasterService is very powerful and can create quite complex queries on master data. However, note that complex queries will require corresponding HW resources for both the iWay MDS engine and underlying database storage. This particular example executes about 10 SQL queries just for one call.


iWay Software