1

I recently tried to populate a neo4j test database using this code :

WITH ["Paul","Graham","Voord","Heisenberg","Earles","Grey","Herzog","Griffith","Rogers","Huxley","Waldorf","Astor","Mellon","Humphrey","Messerschmidt","Carmichael","Buchanan","Dalton","Valentino","Meyerholz","Ellington","Abernathy","Harrington","Monroe","Rutherford","Vanderbilt","Montgomery","Worthington","Fitzwilliam","Covington","Hollingsworth"]
AS names,
["Associates",""]
AS suffixes
FOREACH (r IN range(0,49) | CREATE (:Societe {id:10000+r, name:names[r % size(names)]+" & "+names[(r+3) % size(names)]+" "+suffixes[r % size(suffixes)]}));

FOREACH (r IN range(0,99) | CREATE (:Dossier {id:20000+r, Numero:"0"+(r*4)+100}));

MATCH (s:Societe),(d:Dossier)
WITH s,d
WHERE rand() < 0.1
CREATE (s)-[:CONTAINS]->(d);

But, as you may have guessed, the four last lines create n-to-n relationships between my (:Dossiers) and my (:Societes). What i initially wanted was to create a 1-to-n relationship between these, so that a (:Dossier) can be linked to one (:Societe) at most.

Any idea how to accomplish this ?

Thanks.

Nicolas Marshall
  • 4,186
  • 9
  • 36
  • 54
  • What do you mean by "linked"? Does the direction matter? I.e. is having (d)->(s) the same as having (s)->(d)? And also, are you looking to randomize which Societes and Dossiers are linked? – BtySgtMajor Jul 29 '14 at 15:11
  • Here the direction does not really matter (by that i mean it's not yet required by the rest of my code design). What really matters is the one-to-many aspect : one (:Societe) can be linked to many (:Dossier), but one (:Dossier) can only be linked to one (:Societe) – Nicolas Marshall Jul 29 '14 at 15:25
  • Do you care about randomizing these links/relationships? – BtySgtMajor Jul 29 '14 at 15:51
  • Not especially. But different amounts of outgoing relationships on societes would help (not necessarily random however), as it's intended for front end dev (displaying different amounts of results would help ensure my CSS works in all cases) – Nicolas Marshall Jul 30 '14 at 15:20

2 Answers2

3

Nicolas,

Here's a bit of Cypher to replace your last 4 lines that may get you where you want to go.

MATCH (s:Societe)
WITH s
MATCH (d:Dossier)
WHERE NOT (d)<-[:CONTAINS]-() AND RAND() < 0.1
CREATE (s)-[:CONTAINS]->(d);

MATCH (d:Dossier)-[r:CONTAINS]-()
WITH d, collect(r) AS rels1
WITH d, rels1[1..] AS rels2
FOREACH(q IN rels2 | DELETE q)

The first part reduces the number of interconnections, but doesn't make 1-to-n (which confuses me, but that's the way it goes). The second part trims the relationships so that each dossier is associated with 1 societe. You will likely have dossiers that have no assignment to a societe, but you can find and remove those.

Grace and peace,

Jim

Jim Biard
  • 2,252
  • 11
  • 14
1

You can filter out the dossier that already have a societe.

MATCH (s:Societe), (d:Dossier)
WITH s,d
WHERE rand() < 0.1 and NOT (s)-[:CONTAINS]->()
CREATE (s)-[:CONTAINS]->(d);
Michael Hunger
  • 41,339
  • 3
  • 57
  • 80
  • Unfortunately, this code does not produce 1-to-n relationships (and neither does the version with `WHERE NOT (d)<-[:CONTAINS]-()`). It confuses me as well, as I would expect it to do so. Any probable explanation on this ? – Nicolas Marshall Jul 30 '14 at 15:29