Domain Queries Query Concatenation - Wolfgang-Schuetzelhofer/jcypher GitHub Wiki
Previous | Next | Table of Contents |
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 |