Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-06-2021 08:26 AM
I have a DSL for querying the graph which looks like this:
Graph.query(country: { value: 'Italy' , value: 'Spain', value: 'Greece' }, movie: { title: 'Matrix' })
and produces this cypher query, which works fine:
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WHERE m.title = 'Matrix'
WITH collect(a) as actors, m as movie
UNWIND actors as actor
WITH DISTINCT actor, movie
MATCH (movie)<-[:DIRECTED_BY]-(d:Director)
WHERE (movie)<-[:AVAILABLE_IN]-(c0:Country { value: 'Italy' })
AND (movie)<-[:AVAILABLE_IN]-(c1:Country { value: 'Spain' })
AND (movie)<-[:AVAILABLE_IN]-(c2:Country { value: 'Greece' })
RETURN actor.name, d.name, movie.title
Question: in rare cases a Country
node, for example Spain, will have no edges
, and as such currently the above cypher query would rightly return no results. But is it possible to rewrite the query above so that it would ignore the Country
node if it has no edges
, matching and returning nodes that are connected to the remaining initially defined list of countries i.e. Italy, Greece?
Thanks
11-06-2021 11:37 PM
You could add it as an OPTIONAL MATCH clause after your MATCH
(movie)<-[:AVAILABLE_IN]-(c1:Country { value: 'Spain' })
OR
Maybe you can use some predicate functions like all, any, etc.
Available in the Cypher manuel
OR you can combine OPTIONAL MATCH with WHERE and remove the WHERE from your first clause.
MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WHERE m.title = 'Matrix'
WITH collect(a) as actors, m as movie
UNWIND actors as actor
WITH DISTINCT actor, movie
MATCH (movie)<-[:DIRECTED_BY]-(d:Director)
OPTIONAL MATCH (movie)<-[:AVAILABLE_IN]-(c:Country) WHERE c.value IN ['Italy', 'Spain', 'Greece']
RETURN actor.name, d.name, movie.title
Beware the OPTIONAL MATCH will be repeated for each Director of a movie.
OPTIONAL MATCH will not remove any row, including when the country is null
11-07-2021 05:39 AM
Tried OPTIONAL MATCH
with WHERE
and it works for this use case, however it returns incorrect results for other more complex queries because of WHERE ... IN
filtering. I think what I need is to take all of the Country
nodes that have edges
connecting them to a Movie
and then do a WHERE ... AND
operation - is that possible?
All the sessions of the conference are now available online