Queries

In this section we will look at a few example queries that show how to perform a range of different tasks.

The examples in this section make use of the two Cypher clauses: USE and CALL {}. The syntax is explained in detail in the Cypher Manual:

Query a single graph

Example 1. Reading and returning data from a single graph.
USE example.graphA
MATCH (movie:Movie)
RETURN movie.title AS title

The USE clause at the beginning of the query causes the rest of the query to execute against the example.graphA graph.

Query multiple graphs

Example 2. Reading and returning data from two named graphs
USE example.graphA
MATCH (movie:Movie)
RETURN movie.title AS title
  UNION
USE example.graphB
MATCH (movie:Movie)
RETURN movie.title AS title

The first part of the UNION query executes against the example.graphA graph and the second part executes against the example.graphB graph.

Query all graphs

Example 3. Reading and returning data from all graphs
UNWIND example.graphIds() AS graphId
CALL {
  USE example.graph(graphId)
  MATCH (movie:Movie)
  RETURN movie.title AS title
}
RETURN title

We call the built-in function example.graphIds() to get the graph IDs for all remote graphs in our Fabric setup. We UNWIND the result of that function to get one record per graph ID. The CALL {} subquery is executed once per incoming record. We use a USE clause in the subquery with a dynamic graph lookup, causing the subquery to execute once against each remote graph. At the end of the main query we simply RETURN the title variable.

Query result aggregation

Example 4. Getting the earliest release year of all movies in all graphs
UNWIND example.graphIds() AS graphId
CALL {
  USE example.graph(graphId)
  MATCH (movie:Movie)
  RETURN movie.released AS released
}
RETURN min(released) AS earliest

From each remote graph we return the released property of each movie. At the end of the main query we aggregate across the full result to calculate the global minimum.

Correlated subquery

Example 5. Correlated subquery

Assume that graphA contains American movies and graphB contains European movies. Find all European movies released in the same year as the latest released American movie:

CALL {
  USE example.graphA
  MATCH (movie:Movie)
  RETURN max(movie.released) AS usLatest
}
CALL {
  USE example.graphB
  WITH usLatest
  MATCH (movie:Movie)
  WHERE movie.released = usLatest
  RETURN movie
}
RETURN movie

We query the example.graphA and return the release year of the latest release. We then query the example.graphB. WITH usLatest is an import clause which lets us refer to the usLatest variable inside the subquery. We find all the movies in this graph that fulfill our condition and return them.

It is not possible to switch the current graph in a nested query. For example, the following query is illegal:

Example 6. Illegal correlated subquery
USE example.graphA
MATCH (movie:Movie)
WITH movie.title AS title
CALL {
  USE example.graphB // Cannot swicth from example.graphA
  WITH title
  MATCH (otherMovie:Movie)
  WHERE otherMovie.title STARTS WITH title
  RETURN otherMovie.title AS otherTitle
}
RETURN title, otherTitle

This limitation can be circumvented by having subqueries after one another, but without nesting them.

Updating query

Example 7. Create a new movie node
USE example.graphB
CREATE (m:Movie)
SET m.title = ‘Léon: The Professional’
SET m.tagline = ‘If you want the job done right, hire a professional.’
SET m.released = 1994

Mapping functions

Mapping functions are a common Fabric usage pattern. In the previous examples, graphs were identified by providing static graph names in the query. Fabric may be used in scenarios where graphs are identified by a mapping mechanism that can, for example, identify a key of an object contained in a graph. This can be achieved by using user defined functions or other functions that may be already available. These functions ultimately return the ID of a graph in Fabric.

Mapping functions are commonly used in sharding scenarios. In Fabric, shards are associated to graphs, hence mapping functions are used to identify a graph, i.e. a shard.

Refer to Java Reference → User-defined functions for details on how to create user-defined functions.

Let’s assume that Fabric is setup in order to store and retrieve data associated to nodes with the label user. User nodes are partitioned in several graphs (shards) in Fabric. Each user has a numerical userId, which is unique in all Fabric. We decide on a simple scheme where each user is located on a graph determined by taking the userId modulo the number of graphs. We create a user-defined function which implements the following pseudo code:

sharding.userIdToGraphId(userId) = userId % NUM_SHARDS

Assuming we have supplied a query parameter $userId with the specific userId that we are interested in, we use our function in this way:

USE example.graph( sharding.userIdToGraphId($userId) )
MATCH (u:User) WHERE u.userId = $userId
RETURN u

Fabric built-in functions

Fabric functions are located in a namespace corresponding to a Fabric database in which they are used. The following table provides a description of Fabric built-in functions:

Table 1. Fabric built-in functions
Function Explanation

<fabric database name>.graphIds()

Provides a list of IDs of all remote graph configured for the given Fabric database.

<fabric database name>.graph(graphId)

Maps a graph ID to a Graph. It accepts a graph ID as a parameter and returns a graph representation accepted by USE clause. This function is supported only in USE clauses