0
votes

I'm a newbie of Neo4j and I'm working with a database provided by the examples (Link). I'm trying to create a new relatioship between each actor that acted in the same movie and I run this query

MATCH (p1:Actor)-[:ACTS_IN]->(:Movie)<-[:ACTS_IN]-(p2:Actor) WHERE id(p1)>id(p2) MERGE (p1)-[:ACTED_WITH]->(p2)

But for an unknown reason it creates just some relationships but not others. I've checked both the Node types and the Relationships types but seems that they are all the same, so the query should run correctly in all cases.

If you want to try this thing just download the DB from the link, run the query above, and check this two movies, with Avatar works but not worked with Hart's War

MATCH p=(a)-[]-() WHERE a.title = "Hart's War" OR a.title="Avatar" RETURN p

1
Unfortunately that db hasn't been updated to work with the later versions of Neo4j, you'd have to migrate the data, though I'm not sure if that explains the behavior you're seeing, however. Have you tried using the built-in movies database by using :play movies?InverseFalcon
@InverseFalcon you just need to add dbms.allow_format_migration=true to the configuration file of neo4j and he'll migrate the format for you!user3351109
Tried with the db you linked, your query works just fine, all coactors seem connected properly. Which version of Neo4j are you using, and do you have auto-complete on in your graph results?InverseFalcon
I'm using neo4j 3.2.1 on Windows. Can you please try on that database, after executing my query, to check if also the movie "Hart's War" is correctly connected? About the auto-complete, I have no idea, I just installed neo4j with the default settings. I'll check!user3351109
I'm able to replicate the problem with community version 3.2.1 on Mac. I'll see if I can give it a closer look soon.InverseFalcon

1 Answers

0
votes

This query should do what you need:

MATCH (p1:Actor)-[:ACTS_IN]->(m:Movie)
MATCH (p2:Actor)-[:ACTS_IN]->(m)
WHERE p2 <> p1
OPTIONAL MATCH (p1)-[r:ACTED_WITH]-(p2)
FOREACH (n IN (CASE WHEN r IS NULL THEN [0] ELSE [] END) |
    MERGE (p1)-[:ACTED_WITH]->(p2)  
)

I do not know if this way is the best to do this, but I believe this works.

To create the :ACTED_WITH relationship only once between two nodes (and not (a)-[:ACTED_WHT]->(b) and (a)<-[:ACTED_WHT]-(b)) I'm using this trick. Basicaly I'm simulating an IF condition using FOREACH and CASE statements.

Tested with Neo4j 3.2.

Output