3
votes

I'm running this query:

MATCH (a:TEST:LOC1),(b:TEST_JOIN:LOC1),(c:TEST:LOC1)
WHERE a._out = b._in and b._out = c._in and c._text = 'P'
CREATE (a)-[r:TEST_JOIN]->(c)

It runs very slowly, and the execution plan says: "This query builds a cartesian product between disconnected patterns"

All the properties are indexed and I have tried:

MATCH (c:TEST:LOC1) where c._text='P' with c
MATCH (a:TEST:LOC1),(b:TEST_JOIN:LOC1)
WHERE a._out = b._in and b._out = c._in
CREATE (a)-[r:TEST_JOIN]->(c)

Sorry if this is basic. Does anyone know how to optimise this? Many thanks in advance.

2
Extra info: 6000 nodes total. a = 900 nodes, b = 3400 nodes, c = 85 nodes. - ChrisE

2 Answers

6
votes

I would try this

MATCH (c:TEST:LOC1) where c._text='P' with c
MATCH (b:TEST_JOIN:LOC1) where b._out = c._in with b, c
Match (a:Test:LOC1) WHERE a._out = b._in with a, c
CREATE (a)-[r:TEST_JOIN]->(c)
0
votes

The problem is that amongst your 3 nodes (a, b and c) there are no relationships. You are asking the database to grab all a nodes ,all b nodes and all c nodes and then filter the down by your where clause. That's a cartesian product (https://en.wikipedia.org/wiki/Cartesian_product) and its an indication that your model is incorrect.

Based on your comments it sounds like you want relationships like

 (a)-[something]->(b)-[somethingElse]->(c)

That is something you need to setup before you do your query so that you can use cypher to match based on a graph pattern.