I have an exercise where I have to find actors which acted ONLY in the movie given in params. The problem is that I'm not sure if it's possible to do in pure neo4j query or do I have to make it using some JS' stuff. My idea was to take all actors which play in the movie, save them in some const and then for each of actor find movies and count them and then somehow filter the actors, which has only one movie in some array maybe?
Thank you in advance for any advice.
router.get('/:id/distinct_actors', async (req, res) => {
const session = driver.session();
let data=[]
await session
.run(`MATCH (a: Actor)-[r: ACTED_IN]->(m: Movie) WHERE id(m)= ${req.params.id} RETURN m.title, a.name`)
.subscribe({
onKeys: keys => {
console.log(keys)
},
onNext: records => {
data.push({
title: records.get('m.title'),
actor_name: records.get('a.name')
})
console.log(data)
//console.log(records.get('a.name'))
//console.log(records.get('ID(a)').toString())
},
onCompleted: () => {
session.close()
return res.send(data)
}
})
});
You may be able to use UNWIND, something like this:
MATCH (a: Actor)-[r: ACTED_IN]->(m: Movie) WHERE id(m)= ${req.params.id}
WITH m, COLLECT( a ) AS ACTORS
UNWIND ACTORS AS a
MATCH (a) WHERE NOT EXISTS( (m)<-[:ACTED_IN]-(a)-[:ACTED_IN]->(b:Movie) )
RETURN m.title, a.name;
Sorry I haven't tried this, but basically you get all actors who acted in your target movie, put them in an array (via COLLECT), and then UNWIND the array and filter out the actors where there exists a path linking them to some other movie than 'm'.
I guess you can do this:
MATCH (myMovie:Movie)
WHERE id(myMovie)= ${req.params.id}
WITH myMovie
MATCH (a:Actor)
WHERE [(a)-[:ACTED_IN]->(m:Movie) | m ] = [myMovie]
RETURN a.name,myMovie.title