Domain Queries Query Concatenation

Wolfgang Schuetzelhofer edited this page Jul 31, 2017 · 5 revisions
Previous Next Table of Contents

Domain Queries

Query Concatenation

Query Concatenation allows to use results of one query as starting points of other queries, thus providing to reduce complexity of single queries.
With Query Concatenation you can create a DomainObjectMatch for a certain query based on the DomainObjectMatch of a previously formulated query. Or you can create a DomainObjectMatch based on domain object(s) resulting from the previous execution of another query.
Given you have a query which matches addresses of a person 'John Smith' (see below).

// create a DomainQuery object
DomainQuery q = domainAccess.createQuery();
// create a DomainObjectMatch for objects of type Person
DomainObjectMatch<Person> j_smithMatch = q.createMatch(Person.class);

// Constrain the set of Persons to contain
// 'John Smith' only
q.WHERE(j_smithMatch.atttribute("lastName")).EQUALS("Smith");
q.WHERE(j_smithMatch.atttribute("firstName")).EQUALS("John");
		
// Traverse forward, start with 'John Smith'
// (j_smithMatch is constraint to match 'John Smith' only),
// navigate attribute 'addresses',
// end matching objects of type Address.
DomainObjectMatch<Address> j_smith_AddressesMatch =
   q.TRAVERSE_FROM(j_smithMatch).FORTH("addresses").TO(Address.class);

Then you can use the DomainObjectMatch for these addresses 'j_smith_AddressesMatch' as starting point for a subsequent query.

// create a DomainQuery object
DomainQuery q1 = domainAccess.createQuery();
// now create a DomainObjectMatch for objects of type Address,
// which is derived from a DomainObjectMatch of the previous query
DomainObjectMatch<Address> addressesMatch =
   q1.createMatchFrom(j_smith_AddressesMatch);

// you can then go on with formulating query expressions
// using the newly created DomainObjectMatch.

In another scenario you may have executed the first query from above.

// execute the query
DomainQueryResult result = q.execute();
// retrieve the list of matching domain objects
// (i.e. all addresses of 'John Smith')
List<Address> j_smith_Addresses = result.resultOf(j_smith_AddressesMatch);
		
/**
 * You can work with the addresses retrieved
 */
// with m_street you have a distinct address at hand.
// In the example provided with 'jcypher_samples'
// this will be 'Market Street 20'
Address m_street = j_smith_Addresses.get(0);

Then you can take one or more domain object(s) to be used as starting point(s) in subsequent queries.

// create a DomainQuery object
DomainQuery q1 = domainAccess.createQuery();
// create a DomainObjectMatch from the result of a previous query
DomainObjectMatch<Address> m_streetMatch = q1.createMatchFor(m_street);
		
// Traverse backwards, start with the address resulting from
// a previous query ('Market Street 20' in this case),
// navigate backwards via attribute 'addresses',
// end matching objects of type Person.
DomainObjectMatch<Person> residentsMatch =
   q1.TRAVERSE_FROM(m_streetMatch).BACK("addresses")
      .TO(Person.class);
// order the result by attribute 'firstName' ascending
q1.ORDER(residentsMatch).BY("firstName");
		
// execute the query
DomainQueryResult result1 = q1.execute();
		
// retrieve the list of matching domain objects.
// It will contain all residents of 'Market Street 20'
// (ordered ascending by firstName).
List<Person> residents = result1.resultOf(residentsMatch);

Note however, that results from one query to be used as starting point(s) for subsequent queries are stored as a list of ids (node ids) in memory. So if one query yields a large number of results, only to be used intermediately to start a subsequent query, this may lead to memory consumption problems.


Previous Next Table of Contents