Cypher: how to use a regex in shortcut match expression? - neo4j

Beginner Cypher query. I know how to use a regex in a MATCH expression:
MATCH (p:Person)
WHERE p.name =~ '(?i).*Rebecca.*'
RETURN p;
And I also know the more compact form for MATCH expressions without regexes:
MATCH (p:Person {name:"Rebecca"})
RETURN p;
But is there any way I can use the regex in the more compact form?

No you can't. Inline queries are only aware of an EQUALS operator.
So
MATCH (n:Person {name:"Rebecca"})
is always translated to name EQUALS Rebecca

Related

Parenthesis-style query equivalence

A cypher query in neo4j can be written with WHERE clause:
match (n:PERSON) where n.name = 'Jonash' return n
But it can be also written with parentheses:
match (n:PERSON {name: 'Jonash'}) return n
Is this always possible for different operators, like contains, > or <?
Since 4.4 you can do node pattern predicates like this:
match (m:Movie where m.title contains "Matrix" and m.released = 1999)
return m
From cypher manual: https://neo4j.com/docs/cypher-manual/current/clauses/where/#node-pattern-predicates
But the short hand (n:Label{propertyKeyName: propertyKeyValue}) syntax is only there for equality.

Writing a case-insensitive Cypher query to match the beginning of a string in Neo4j

I'm having trouble while trying to write a Cypher query that returns all the nodes which their name starts with a certain string. I also need this query to be case insensitive.
Cypher has built in functions for both cases, but I don't know how to combine them
Query for matching the beginning of a string:
MATCH (n) WHERE n.Name STARTS WITH 'Pet' RETURN n
Query for case-insensitive strings
MATCH (n) WHERE n.Name =~ '(?i)ANDR.*' RETURN n
Any help will be appreciated.
For a case insensitive comparison using the STARTS WITH string comparison operator you can use the toLower() string function to convert each side of the comparison to lower case. For example:
MATCH (n)
WHERE toLower(n.name) STARTS WITH toLower('Pet')
RETURN n

Replace regular expressions in cypher

I can search for regular expressions in cypher
MATCH (n:model) WHERE n.name =~ '.*&.*;.*' RETURN n.name
but can I also replace them? I would like to write something like
MATCH (n:model) RETURN replace(n.name, ~'&.*;', '_');
There is a replace function in cypher, but it does not replace regexps, just simple strings.
Maybe a feature request for replaceRegex could be done?
An workaround would be to do this programatically, after you return the names (if you use call cypher queries from another application).

Using Union results to filter a match using With

I wish to use the results of a UNION (n) as a filter for a subsequent match.
MATCH (n:Thing)-<<Insert valid match filters here>>
RETURN n
UNION
MATCH (n:Thing)-<<Insert a different set of match filters here>>
RETURN n;
n feeds into:
MATCH (n)-[:RELTYPE1]->(a:Artifact);
RETURN a;
I would expect to use a WITH statement, but I've struggled to figure out how structure the statement.
MATCH (n:Thing)-<<Insert valid match filters here>>
RETURN n
UNION
MATCH (n:Thing)-<<Insert a different set of match filters here>>
WITH n
MATCH (n)-[:RELTYPE1]->(a:Artifact);
RETURN a;
This was my original attempt, but the WITH is interpreted as the start of subquery of the UNION's second match (which makes sense).
I can see a few inelegant ways to make this work, but what is the proper approach?
I have been looking at your union example and it makes sense to me but I cannot see how I could make it work. But I am certainly not the guy with all of the answers. Is there a reason you couldn't do something like this though...
MATCH (n:Thing)
WHERE n.name = 'A'
WITH collect(n) as n1
MATCH (n:Thing)
WHERE n.name = 'B'
WITH n1 + collect(n) AS both
UNWIND both AS n
MATCH (n)-[:RELTYPE1]->(a:Artifact);
RETURN a;

Running a case-insensitive cypher query

Is it possible to run a case-insensitive cypher query on neo4j?
Try that: http://console.neo4j.org/
When I type into this:
start n=node(*)
match n-[]->m
where (m.name="Neo")
return m
it returns one row. But when I type into this:
start n=node(*)
match n-[]->m
where (m.name="neo")
return m
it does not return anything; because the name is saved as "Neo". Is there a simple way to run case-insensitive queries?
Yes, by using case insensitive regular expressions:
WHERE m.name =~ '(?i)neo'
https://neo4j.com/docs/cypher-manual/current/clauses/where/#case-insensitive-regular-expressions
Another way would be:
WHERE LOWER(m.Name) = LOWER("Neo")
And if you are using the Neo4j Client (.NET):
Client.Cypher.Match("(m:Entity)")
.Where("LOWER(m.Name) = LOWER({name})")
.WithParam("name", inputName)
.Return(m => m.As<Entity>())
.Results
.FirstOrDefault();
If anybody is looking on how to do this with a parameter, I managed to do it like this.
query = "{}{}{}".format('Match (n) WHERE n.pageName =~ "'"(?i)", name, '" RETURN n')
and "name" is the variable or your parameter
You can pass a parameter to the case insensitive regular expression like:
WHERE m.name =~'(?i)({param})

Resources