ekkis
ekkis

Reputation: 10226

How to create conditional relationships?

I have a system that is run by an organization to implement a certain function, thus I have the relationship:

Organization → Function → System

but sometimes the function remains unknown, in which case I want to bind the system directly to the organization:

Organization → System

how do I write this kind of thing?

the System contains attributes that are used for creating these relationships e.g.

create (s:System {id: 'x', Organization: 'MST', Function: 'CM'})

or

create (s:System {id: 'x', Organization: 'MST'})

which means I can find the nodes like this:

match (s:System), (o:Organization {Code: s.Organization})
optional match (f:Function {Code: s.Function})

...but how do I create the relationship?

Upvotes: 0

Views: 1640

Answers (2)

ekkis
ekkis

Reputation: 10226

I found Mark Needham's post:

http://www.markhneedham.com/blog/2014/06/17/neo4j-load-csv-handling-conditionals/

...which offers a torturous syntax but provides a solution. Is there a nicer way to accomplish this?

match (s:System), (o:Organization {Code: s.Organization}) 
optional match (d:Function {Code: s.Function}) 
foreach (n in (case when s.Function is null then [1] else [] end) | 
  create (o)-[:Runs]->(s)
) 
foreach (n in (case when s.Function is not null then [1] else [] end) | 
  create (o)-[:Function]->(f)-[:SupportedBy]->(s)
);

Upvotes: 1

cybersam
cybersam

Reputation: 66999

Since you always have System nodes, you could re-arrange your data model to look like this

(:Org {Code: 1})-[:HAS_SYSTEM]->(:System {id: 2})-[:HAS_FUNCTION]->(:Function {Code: 3})

The HAS_FUNCTION relationship and the Function node would be optional.

So, if you wanted to find the System(s) for Org Code 1 that have Function Code 3, you could do this:

MATCH (:Org {Code: 1})-[:HAS_SYSTEM]->(s:System)-[:HAS_FUNCTION]->(:Function {Code: 3})
RETURN s;

Upvotes: 0

Related Questions