kkulkarn
kkulkarn

Reputation: 345

Neo4J: cypher for relations

I have a hierarchy in the following format:

Application.A <-[:belongs_to {roles:instance}]-Instance.A1-[:depends_on {roles:host}]-> Host.vm1

implying Application A has an instance A1 which is running on Host vm1 with the relation "belongs_to" and "depends_on".

Instance.A1-[:depends_on {roles:instance}]-> Database db1 <-[:belongs_to]-Instance.dbNode1-[:depends_on {roles:host}]-> Host.vm2

implying instance A1 of Application A depends on Database db1 that has an Instance dbNode1 running on Host vm2.

I am able to write individual cyphers and process the result in my java API.

I am trying to write a a single cypher that will take Application as input (in this case A) & return the whole hierarchy.

Something like this....

A.A1.vm1.db1.dbNode1.vm2

Is this doable? If yes, would appreciate some pointers.

Thanks.

Upvotes: 0

Views: 65

Answers (1)

cybersam
cybersam

Reputation: 66989

It is certainly possible.

I would advise against putting, in your relationships, properties that would need to be used for matching purposes -- since Cypher does not allow you to index them yet. You should just have specific relationship types.

Also, to indicate which instance of the db1 DB is being used by a1, you really need a direct relationship between a1 and dbNode1. You cannot only have a relationship between a1 and db1, since it would not be clear which instance of db1 is being used by a1.

Here is an example of what you could do:

MATCH
  (a1:Instance)-[:is_instance_of]->(a:Application {name: "MyApp"}),
  (a1)-[:runs_on_host]->(vm1:Host),
  (a1)-[:uses_db_type]->(db1:Database),
  (a1)-[:uses_db_instance]->(dbNode1:Instance)-[:is_instance_of]->(db1),
  (dbNode1)-[:runs_on_host]->(vm2:Host)
RETURN a.name + "." + a1.name + "." + vm1.name + "." + db1.name + "." + dbNode1.name + "." + vm2.name AS result;

Note that this simple query would not match an app instance that does not use a DB. If you need to match such instances as well, you can use an OPTIONAL MATCH clause:

MATCH
  (a1:Instance)-[:is_instance_of]->(a:Application {name: "MyApp"}),
  (a1)-[:runs_on_host]->(vm1:Host)
OPTIONAL MATCH
  (a1)-[:uses_db_type]->(db1:Database),
  (a1)-[:uses_db_instance]->(dbNode1:Instance)-[:is_instance_of]->(db1),
  (dbNode1)-[:runs_on_host]->(vm2:Host)
RETURN
  CASE WHEN db1 IS NULL THEN a.name + "." + a1.name + "." + vm1.name
       ELSE a.name + "." + a1.name + "." + vm1.name + "." + db1.name + "." + dbNode1.name + "." + vm2.name
       END
  AS result;

Upvotes: 3

Related Questions