Reputation: 2158
I try to run the following query, where I have 10 chains in database and 10 Countries. and using the array of 20 addresses. Then I loop through those to create a store for each combination of country, chain and address, expecting 10*10*20 combinations - 2000 stores. But instead, query runs until around 200 000 records are created and then halts with unknown error.
MATCH (Chains:Chain), (Countries:Country)
WITH Collect(Chains) as ch,
Collect(Countries) as cou,
['Ullevål','Blindern','Centrum','Kringså','Lysaker','Skøyen','Fornebu','Stortinget','Nationalteatre','KarlJohan',
'Gamle','Grunerløkka','Grønland','Majorstuen','Snarøya','Asker','Sandvika','Drammen','Gothenburg','Stockholm'] as addresses
FOREACH(country in cou |
FOREACH (c in ch |
FOREACH (a in addresses |
CREATE (s:Store {name:c.name+"_"+a, address:a})
CREATE (s-[:BELONGS_TO]->c)
CREATE (s-[:IN]->country) )))
Upvotes: 1
Views: 2396
Reputation: 7790
If you have the following data...
FOREACH (i IN RANGE(1, 10) |
CREATE (:Chain {name:'Chain' + i}),
(:Country {name:'Country' + i})
)
...the first part of your query
MATCH (Chains:Chain), (Countries:Country)
WITH COLLECT(Chains) AS ch, COLLECT(Countries) AS cou
will result in length-100 collections for both ch
and cou
, since the MATCH
is retrieving a Cartesian product (10^2 = 100). So that is where your 200,000 records are coming from: 100 * 100 * 20. You can verify this with the following:
MATCH (Chains:Chain), (Countries:Country)
WITH COLLECT(Chains) AS ch, COLLECT(Countries) AS cou
RETURN LENGTH(ch), LENGTH(cou)
which will tell you that each collection is length-100:
LENGTH(ch) LENGTH(cou)
100 100
You can fix this by using COLLECT(DISTINCT thing)
in the first part of your query to collect only the unique things...
MATCH (Chains:Chain), (Countries:Country)
WITH COLLECT(DISTINCT Chains) AS ch, COLLECT(DISTINCT Countries) AS cou
RETURN LENGTH(ch), LENGTH(cou)
...which will tell you that ch
and cou
are length-10 collections:
LENGTH(ch) LENGTH(cou)
10 10
Now your nested FOREACH
will be creating 10 * 10 * 20 = 2000 records:
MATCH (Chains:Chain), (Countries:Country)
WITH Collect(DISTINCT Chains) as ch,
Collect(DISTINCT Countries) as cou,
['Ullevål','Blindern','Centrum','Kringså','Lysaker','Skøyen','Fornebu','Stortinget','Nationalteatre','KarlJohan',
'Gamle','Grunerløkka','Grønland','Majorstuen','Snarøya','Asker','Sandvika','Drammen','Gothenburg','Stockholm'] as addresses
FOREACH(country in cou |
FOREACH (c in ch |
FOREACH (a in addresses |
CREATE (s:Store {name:c.name+"_"+a, address:a})
CREATE (s-[:BELONGS_TO]->c)
CREATE (s-[:IN]->country) )))
"Added 2000 labels, created 2000 nodes, set 4000 properties, created 4000 relationships, returned 0 rows in 1262 ms."
Upvotes: 5