It appears that LIKE is not supported in Cypher queries.
Is there any other construct that would perform the same task?
For instance:
start n = node(*) where n.Name LIKE('%SUBSTRING%') return n.Name, n;
using regular expressions:
http://neo4j.com/docs/developer-manual/current/#query-where-regex
start n = node(*) where n.Name =~ '.*SUBSTRING.*' return n.Name, n;
As of version 2.0, the preferred syntax uses MATCH.
e.g.
MATCH (n) where n.Name =~ '.*SUBSTRING.*' return n.Name, n;
No Regexps needed:
start n = node(*) where n.Name contains "substring" return n.Name, n;
Go to the cypher refcard and scroll down to the Predicates section. You will find this and other useful stuff.
Want case-insensitive? Convert to lower case:
start n = node(*) where lower(n.Name) contains lower("substring") return n.Name, n;
If you want to make it case insensitive
MATCH (n) WHERE n.name =~ '(?i).*SUBSTRING.*' RETURN n;
Related
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.
Think to a Cypher query like this:
MATCH (n)
WHERE <complex condition>
RETURN n
But I need to return also possible edges between those nodes. Is it possible?
MATCH (n)
WHERE <complex condition>
WITH COLLECT(n) AS nodes
MATCH (n)-[r]-(m)
WHERE (n IN nodes) AND (m in nodes)
AND id(n)>id(m)
RETURN n,r,m
There are three node types: A, B and C.
I need all the A's and B's and only the C's that participate in exactly one relationship.
match (n)
where n:A or n:B or (n:C)-[]-()
with count(n) as countOfRels
where countOfRels > 0
return n
Not close, I know. I'm not sure where to go from here.
It's a bit strange that A, B and C do not seem to be related ... but here's how you could solve your question for C :
MATCH (n:C)
WHERE size((n)-[]-()) = 1
RETURN n
UNION
MATCH (n:A)
RETURN n
UNION
MATCH (n:B)
RETURN n;
Hope this helps.
Regards,
Tom
you can use this
match(n)
where n:A OR n:B OR (n:C)-[r]-()
with count(r) as countOfRels
where countOfRels > 0
return n
Hope this helps.
You can do MATCH (a)--() WHERE NOT ()--(a)--() to match "nodes with only one relation". After that, You can use UNION or COLLECT()+UNWIND to combine the separate queries into one row result set.
// using Union
MATCH (n:C)--()
WHERE NOT ()--(n)--()
RETURN n
UNION
MATCH (n:A)
RETURN n
UNION
MATCH (n:B)
RETURN n;
// Using collect
OPTIONAL MATCH (a:A)
OPTIONAL MATCH (b:B)
OPTIONAL MATCH (c:C)--() WHERE NOT ()--(c)--()
WITH COLLECT(a)+COLLECT(b)+COLLECT(c) as nodez
UNWIND nodez as n
RETURN DISTINCT n
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;
I'm playing with cypher and I have some simple aggregation going on for me.
MATCH (p:Person)-[:HAS_CAR]->(n:Car)
RETURN n, count(p)
MATCH (p:Person)-[:HAS_APARTMENT]->(n:Apartment)
RETURN n, count(p)
MATCH (p:Person)-[:HAS_HOUSE]->(n:House)
RETURN n, count(p)
The problem is that I have to make 3 trips to the database to get all those results together. The problematic thing about that is that those queries are the last MATCH statement in a much bigger chain. Like this:
MATCH (:City { Id: 10})<-[:LIVES_IN]-(p:Person)
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH ...
WITH p
MATCH p-[:HAS_CAR]->(n:Car)
RETURN n, count(p)
After all those MATCH ... WITH statements, only a few person nodes are matched so the last part of the query is very fast, but the initial part is not. I can't help but think that this could be improved because all three queries share a lot of statements.
I came up with this:
...
MATCH p-[:HAS_CAR|HAS_APARTMENT|HAS_HOUSE]->(n)
RETURN n, labels(n), count(p)
And I can work with that. But what if I wanted to mix in something like this:
MATCH p-[:KNOWS]->(:Person)-[:HAS_BIKE]->(n:Bike)
RETURN n, count(p)
Or even:
MATCH p-[:KNOWS]->(:Person)-[:HAS_BIKE|HAS_BOAT]->(n)
RETURN n, labels(n), count(p)
Can all of this be done in a single query and how?
Sometimes you need to use collections instead of rows to merge aggregation queries together and pass them along. This strategy might help... For example:
MATCH (p:Person)-[:HAS_CAR]->(car:Car)
WITH car, count(p) carCount
WITH collect({car:car, count:carCount}) as carCounts
MATCH (p:Person)-[:HAS_APARTMENT]->(n:Apartment)
WITH n, count(p) as apartmentCount, carCounts
RETURN collect({apartment:n, count:apartmentCount}) as apartmentCounts, carCounts
Update (see comments)--this lets you pass along the results of a filter and do a quick id lookup to find them again:
MATCH (p:Person)
WHERE p.name = "John" // or whatever else you need to filter on
WITH collect(id(p)) as pids
MATCH (p)-[:HAS_CAR]->(car:Car)
WHERE id(p) IN pids
WITH car, count(p) carCount, pids
WITH collect({car:car, count:carCount}) as carCounts, pids
MATCH (p)-[:HAS_APARTMENT]->(n:Apartment)
WHERE id(p) IN pids
WITH n, count(p) as apartmentCount, carCounts
RETURN collect({apartment:n, count:apartmentCount}) as apartmentCounts, carCounts