Expressions

Expressions

The following sections describe some of the other supported features.

String operators

Apart from comparison and concatenation operators Cypher provides special string operators for easier matching of substrings:

OperatorDescription
a STARTS WITH bReturns true if the prefix of string a is equal to string b.
a ENDS WITH bReturns true if the suffix of string a is equal to string b.
a CONTAINS bReturns true if some substring of string a is equal to string b.

For example, if you want to return the names of all Person nodes where the name starts with Joh the query would be:

MATCH (p:Person)
WHERE p.name STARTS WITH 'Joh'
RETURN p.name;

Parameters

When automating the queries for Memgraph, it comes in handy to change only some parts of the query. Usually, these parts are values that are used for filtering results or similar, while the rest of the query remains the same.

Parameters allow reusing the same query but with different parameter values. The syntax uses the $ symbol to designate a parameter name. We don't allow old Cypher parameter syntax using curly braces. For example, you can parameterize filtering a node property:

MATCH (node1 {property: $propertyValue}) RETURN node1;

If you want to update a property of a node, you can use the following:

MATCH (n) SET n.propertyValue = $propertyNewValue;

You can use parameters instead of any literal in the query. For example, if you want to filter nodes based on a specific label, you can execute the following query:

MATCH (n:$label)
RETURN n;

Using parameters as property maps is partially supported, it isn't supported in MATCH nor MERGE clause. For example, the following query is illegal:

MATCH (n $propertyMap) RETURN n;

but this is supported:

CREATE (n $propertyMap) RETURN n;

Memgraph also supports parameters in LIMIT clauses. For example:

MATCH (n) RETURN n LIMIT $limit;

Additionally, Memgraph supports parameters for LOAD CSV queries. For instance:

LOAD CSV FROM $file AS row CREATE (:Node {property: row.property});

To use parameters with a Python driver, use the following syntax:

session.run('CREATE (alice:Person {name: $name, age: $ageValue})',
            name='Alice', ageValue=22).consume()

To do the same with labels:

session.run('CREATE (alice:$label {name: $name, age: $ageValue}',
            label='Person', name='Alice', ageValue=22)).consume()

To use a property map as a parameter, you can use the following syntax:

session.run('CREATE (alice:Person $propertyMap)', propertymap={"name": "Alice"}).consume()

To use parameters whose names are integers, you will need to wrap parameters in a dictionary and convert them to strings before running a query:

session.run('CREATE (alice:Person {name: $0, age: $1})',
            {'0': "Alice", '1': 22}).consume()

To use parameters with some other driver, please consult the appropriate documentation.

CASE

Conditional expressions can be expressed in the Cypher language with the CASE expression. A simple form is used to compare an expression against multiple predicates. For the first matched predicate result of the expression provided after the THEN keyword is returned. If no expression is matched value following ELSE is returned is provided, or null if ELSE is not used:

MATCH (n)
RETURN CASE n.currency WHEN "DOLLAR" THEN "$" WHEN "EURO" THEN "€" ELSE "UNKNOWN" END;

In generic form, you don't need to provide an expression whose value is compared to predicates, but you can list multiple predicates and the first one that evaluates to true is matched:

MATCH (n)
RETURN CASE WHEN n.height < 30 THEN "short" WHEN n.height > 300 THEN "tall" END;

Most expressions that take null as input will produce null. This includes boolean expressions that are used as predicates. In this case, anything that is not true is interpreted as being false. This also concludes that logically null!=null.

The exists() function cannot be used with the CASE clause.

Pattern comprehension

Pattern comprehension is a syntactic construct available in Cypher for creating a list based on matchings of a pattern. A pattern comprehension matches the specified pattern like a normal MATCH clause, with predicates like a normal WHERE clause, but yields a custom projection as specified.

Currently, pattern comprehensions are supported in RETURN and WITH clauses.

For example, if you want to get person names along with the release years and titles of all the movies with Matrix in their title that they are related to the query would be:

MATCH (n:Person)
RETURN n.name,
    [(n)-->(b:Movie) WHERE b.title CONTAINS 'Matrix' | b.released] AS years,
    [(n)-->(c:Movie) WHERE c.title CONTAINS 'Matrix' | c.title] AS titles;

For example, the following query finds person names with more than 5 characters, treats them as actors, and extracts the titles and releases years of the movies they're linked to (provided those movies were released after the year 2000), then returns all this information as lists, alongside the corresponding actor's name.

MATCH (n:Person) WHERE size(n.name) > 5
WITH
    n AS actor,
    [(n)-->(m) WHERE m.released > 2000 | m.title] AS titles,
    [(n)-->(m) WHERE m.released > 2000 | m.released] AS years
RETURN actor.name, years, titles;

The whole predicate, including the WHERE keyword, is optional and may be omitted.

Storing lists as properties

It is possible to store homogenous lists of simple values as properties. For example, the following query creates a list from the title properties of the Movie nodes connected to Keanu Reeves. It then sets that list as a resume property on Keanu Reeves.

MATCH (keanu:Person {name: 'Keanu Reeves'})
WITH keanu,[(keanu)-->(b:Movie) | b.title] AS movieTitles
SET keanu.resume = movieTitles
RETURN keanu.resume

It is not, however, possible to store heterogeneous lists as properties. For example, the following query, which tries to set a list including both the title and the released properties as the resume property of Keanu Reeves will fail. This is because the title property values are stored as STRING values, while the released property values are stored as INTEGER values.

MATCH (keanu:Person {name: 'Keanu Reeves'})
WITH keanu,[(keanu)-->(b:Movie) | b.title]  + [(keanu)-->(b:Movie) | b.released] AS movieTitles
SET keanu.resume = movieTitles
RETURN keanu.resume