2015-04-30 2 views
0

У меня есть иерархия в следующем формате:Neo4j: высчитывать отношений

< Application.A - [: belongs_to {роли: экземпляр}] - Instance.A1 - [: depends_on {ролей: хост}] - > Host.vm1

подразумевая, что приложение A имеет экземпляр A1, который запущен на Host vm1 с отношением «принадлежит_to» и «depend_on».

Instance.A1 - [: depends_on {роли: экземпляра}] -> базы данных DB1 < - [: belongs_to] -Instance.dbNode1 - [: depends_on {роли: хозяева}] -> Host.vm2

подразумевающий экземпляр A1 приложения A зависит от базы данных db1, которая имеет экземпляр dbNode1, запущенный на Host vm2.

Я могу написать отдельные cyphers и обработать результат в моем API Java.

Я пытаюсь написать один cypher, который примет приложение в качестве входного (в данном случае A) & возвращает всю иерархию.

Что-то вроде этого ....

A.A1.vm1.db1.dbNode1.vm2

Является ли это выполнимо? Если да, то оценили бы некоторые указатели.

Спасибо.

+0

не должен 'A1' на самом деле зависит от' dbNode1', вместо 'db1'? – cybersam

+0

База данных может иметь несколько узлов. Таким образом, отношение должно быть связано с базой данных (поскольку база данных выполняет балансировку нагрузки). – kkulkarn

+0

ОК, спасибо за разъяснение. – cybersam

ответ

3

Это, безусловно, возможно.

Я бы посоветовал не вводить в ваши отношения свойства, которые необходимо использовать для сопоставления целей, поскольку Cypher не позволяет вам их индексировать. У вас должны быть только определенные типы отношений.

Кроме того, чтобы указать, какой экземпляр db1 БД используется a1, вам действительно нужна прямая связь между a1 и dbNode1. Вы можете не только иметь отношения между a1 и db1, так как не ясно, какой экземпляр db1 используется a1.

Вот пример того, что вы могли бы сделать:

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; 

Обратите внимание, что этот простой запрос не будет соответствовать экземпляр приложения, который не использует БД. Если вам нужно, чтобы соответствовать таким случаям, как хорошо, вы можете использовать OPTIONAL MATCH пункт:

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; 
+0

Отлично .. это в точности соответствует тому, что я искал !! – kkulkarn

Смежные вопросы