Variables

Variables can be used in Cypher® to reference parts of a pattern and hold values. For example:

MATCH (m:Movie)
RETURN m

The variable m refers to a node matched in the pattern (:Movie). The node is then returned.

Writing dynamic Cypher queries can be challenging as the resulting variables need to have unique names that correctly reference the values. The advantage of using Cypher Builder is that JavaScript references remove the need to track variable names, thus providing another layer of abstraction.

Types

Cypher Builder distinguishes four types of variables:

  • Node: holds a reference to a node matched in a pattern.

  • Relationship: holds a reference to a relationship in a pattern.

  • Variable: generic variable reference.

  • Path: a variable to hold a path.

All Cypher Builder variables are virtual references to a Cypher variable that will be translated to a unique name.

Defining a variable

An arbitrary Cypher variable can be defined with:

const myVar = new Cypher.Variable();

This variable can then be used as an expression in any clause that supports variables, for instance:

const myVar = new Cypher.Variable();
const query = new Cypher.Return(myVar)
RETURN var0

The name var0 is automatically generated when .build() is called, so that it prevents name collision. If the variable is reused, the same name will be used in the generated Cypher, for instance:

const myVar = new Cypher.Variable();
const query = new Cypher.With(myVar).return(myVar);
WITH var0
RETURN var0

Each instance you create of a variable is associated with a different name:

const withVar = new Cypher.Variable();
const returnVar = new Cypher.Variable();
const query = new Cypher.With(withVar).return(returnVar);
WITH var0
RETURN var1

Nodes and relationships

Nodes and relationships are sugar syntax for variables. They can be used in Patterns, for example:

const movie = new Cypher.Node();
const relationship = new Cypher.Relationship();

const pattern = new Cypher.Pattern(movie, { labels: ["Movie"] }).related(relationship, { type: "ACTED_IN" }).to();
const match = new Cypher.Match(pattern).return(movie);
MATCH (this0:Movie)-[this1:ACTED_IN]->()
RETURN this0

In this example, the node variable movie is created and then used in the MATCH and RETURN clauses.

In the translated Cypher, you can see how the node variable is translated to the Cypher variable this0, while the relationship is assigned to this1. These names are not defined in your JavaScript code, but are automatically generated when the query is built with .build(). The labels and types passed to the Node and Relationship variables are used in the pattern.

Passing labels or type to Nodes and Relationships is deprecated. Currently, the classes Node and Relationship are just sugar syntax for Variables and can be used in the same places. The only difference is that variables will be automatically named var while nodes and relationships will be named this

Path

Path variables can be used for path assignment in patterns, for example:

MATCH p0 = (this1)-[this2:ACTED_IN]->(this3)
RETURN p0

To assign a path variable, use the method .assignToPath in the relevant clause and pass a new Path() instance:

const path = new Cypher.Path();

const query = new Cypher.Match(pattern).assignToPath(path).return(path);

Named variables

By default, variables do not have a name; a unique name/id is generated at build time to avoid collisions. However, in some cases, you may want to generate a query with a specific name. To do this, all variable types must have a counterpart Named class, for instance:

  • NamedVariable

  • NamedNode

  • NamedRelationship

  • NamedPath

These can be used in the same fashion as normal variables, but a name must be provided when creating them:

const movie = new Cypher.NamedNode("n");
const match = new Cypher.Match(movie, { labels: ["Movie"] }).return(movie);
MATCH (n:Movie)
RETURN n

Properties

Variables such as nodes or maps may contain properties. To access these properties in the generated Cypher, you can use the method .property on variables:

const movie = new Cypher.Node()
const query = new Cypher.Match(movie, { labels: ["Movie"] }).return(movie.property("title"));
MATCH(this0:Movie)
RETURN this0.title

Nested properties

Nested properties can also be accessed either by passing multiple parameters or concatenating calls to .property:

new Cypher.Variable().property("movie", "title");
new Cypher.Variable().property("movie").property("title")

In both cases, the resulting Cypher should look like this:

var0.movie.title

Expressions

Expressions can also be used as a property key to dynamically access properties:

const movie = new Cypher.Node()

const movieProperty = movie.property(Cypher.plus(new Cypher.Param("ti"), new Cypher.Literal("tle")))
const query = new Cypher.Match(movie, { labels: ["Movie"] }).return(movieProperty);

The query automatically adds square brackets ([]) notation to safely execute the expression:

MATCH(this0:Movie)
RETURN this0[($param0 + $param1)]

Index

Like properties, an index can also be accessed through the method .index:

new Cypher.Variable().index(2);
var0[2]