Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
02-09-2021 05:01 PM
Greetings All,
I'm new to the community and still wrapping my head around Cypher.
I'm playing with a sample dataset in the desktop app, and I want to match all nodes that are a certain distance away from a point, but I do not want to traverse over specific relationship types.
My attempted query is this:
MATCH (p:Program {name: 'Initial Program'})-[x*1..4]-(n)
WHERE NOT x.name = 'IMPLEMENTED_BY' OR x.name = 'CREATED_BY'
RETURN p, n
The CLI gives me this error:
Type mismatch: expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was List<Relationship> (line 2, column 11 (offset: 67))
"WHERE NOT x.name = 'IMPLEMENTED_BY' OR x.name = 'CREATED_BY'"
I glean from this that the variable x
is not an instance of every relationship traversed, but a set of relationships needed to connect each set of matched nodes. This leads to a few different questions:
I spent time in Chapter 3 of the neo4j cypher manual, however I couldn't find an example of filtering off of relationships in a variable multiple traversal scenario.
Thanks ahead of time for patience with a beginner.
02-16-2021 07:23 AM
There are a number of ways to do this. If this was a one hop relationship you could just do this,
MATCH (p:Program {name: 'Initial Program'})-[x]-(n)
WHERE type(x)<> 'IMPLEMENTED_BY' AND type(x)<>'CREATED_BY'
RETURN p, n
However in this case x is a LIST (of relationships)
Here are two ways,
You can specify the relationships you want to explore (instead of the list you want to avoid). for example, this would find all paths of BOUGHT_BY and OWNED_BY relationships, and NOT any other relationship types
MATCH (p:Program {name: 'Initial Program'})-[:BOUGHT_BY|OWNED_BY*1..4]-(n)
RETURN p, n
relationship types are accessed with type(), so you could also write
WITH ['IMPLEMENTED_BY','CREATED_BY'] AS list
MATCH t=(p:Program {name: 'Initial Program'})-[*1..4]-(n)
WHERE none(r in relationships(t) WHERE type(r) in list)
return p, n
Note: t contains each path, you can also access the nodes in a given path with nodes(t)
a few additional notes, food for thought: Your query explores relationships in both directions, and (when possible and it might not be here) it is more efficient to use directed relationships... I would suggest adding a LIMIT statement at the end when developing a query of this kind just to insure it comes back if it finds thousands or millions of paths... or return a count() first just to get a sense of how big the result set is.
All the sessions of the conference are now available online