Получить все подграфы определенного типа в Neo4J

У меня есть набор узлов и отношений, и я хочу получить подграф определенного типа для узла. Чтобы пояснить вопрос, прикрепил изображение к графику.

![введите описание изображения здесь

Узлы, выделенные желтым, соединены узлами, выделенными зеленым, отношением «IS_PART_OF». Когда мы смотрим на приведенный выше фрагмент, желтый узел «8366854» соединен с 4 зелеными узлами «P10398», «P10398-2», «A0A024» и «P02647», где желтый узел «8366931» соединен с 2 зелеными узлами «A0A024». " и "P02647". Таким образом, зеленые узлы «A0A024» и «P02647» являются общими для обоих, и я могу сказать, что желтый узел «8366931» является частью «8366854». Это происходит только в том случае, если все зеленые узлы являются общими для обоих.

Поэтому мой запрос будет представлять собой идентификатор желтого узла, скажем, "8366854", который возвращает все вложенные желтые узлы (в данном случае только "8366931").

Таким образом, для приведенного ниже фрагмента я мог бы сказать:

1) "8366523" является частью "8366848"

2) "8366915" не является частью "8366848", так как не имеет общих зеленых узлов.


person Sreenath S    schedule 21.09.2018    source источник
comment
… и что вы уже пробовали?   -  person Dominique    schedule 21.09.2018


Ответы (2)


Собственно, шифр позволяет выразить это последовательностью инструкций:

  • взять желтый узел и взять всех его зеленых соседей
  • для каждого зеленого соседа найти желтого и его зеленых соседей
  • убедитесь, что для второго желтого соседа каждый зеленый сосед также является соседом первого желтого узла

MATCH (Y1:YELLOW)<-[:IS_PART_OF]-(G:GREEN)
WITH Y1, 
     collect(G) AS greens1
UNWIND greens1 AS G
MATCH (G)-[:IS_PART_OF]->(Y2:YELLOW)<-[:IS_PART_OF]-(G2:GREEN) WHERE Y1 <> Y2
WITH Y1, Y2, greens1, 
     collect(G2) AS greens2 
     WHERE SIZE(greens1) > size(greens2) AND 
           ALL(G IN greens2 WHERE G IN greens1)
RETURN Y1, collect(Y2) AS subs
person stdob--    schedule 21.09.2018

1. Создание графика:

Первый оператор создает узлы, второй — отношения между ними.

CREATE
  (Yellow1:Yellow {name: 'Yellow 1'}),
  (Yellow2:Yellow {name: 'Yellow 2'}),
  (Yellow3:Yellow {name: 'Yellow 3'}),
  (Yellow4:Yellow {name: 'Yellow 4'}),
  (Yellow5:Yellow {name: 'Yellow 5'}),
  (Yellow6:Yellow {name: 'Yellow 6'}),
  (Green1:Green {name: 'Green 1'}),
  (Green2:Green {name: 'Green 2'}),
  (Green3:Green {name: 'Green 3'}),
  (Green4:Green {name: 'Green 4'}),
  (Green5:Green {name: 'Green 5'}),
  (Green6:Green {name: 'Green 6'}),
  (Green7:Green {name: 'Green 7'}),
  (Green8:Green {name: 'Green 8'}),
  (Green9:Green {name: 'Green 9'}),
  (Green10:Green {name: 'Green 10'}),
  (Green11:Green {name: 'Green 11'}),
  (Green12:Green {name: 'Green 12'}),
  (Green13:Green {name: 'Green 13'})

CREATE
// upper graph
  (Green1)-[:IS_PART_OF]->(Yellow1),
  (Green2)-[:IS_PART_OF]->(Yellow1),
  (Green3)-[:IS_PART_OF]->(Yellow1),
  (Green4)-[:IS_PART_OF]->(Yellow1),
  (Green3)-[:IS_PART_OF]->(Yellow2),
  (Green4)-[:IS_PART_OF]->(Yellow2),
// lower graph
  (Green5)-[:IS_PART_OF]->(Yellow3),
  (Green6)-[:IS_PART_OF]->(Yellow3),
  (Green5)-[:IS_PART_OF]->(Yellow4),
  (Green6)-[:IS_PART_OF]->(Yellow4),
  (Green7)-[:IS_PART_OF]->(Yellow4),
  (Green8)-[:IS_PART_OF]->(Yellow4),
  (Green7)-[:IS_PART_OF]->(Yellow5),
  (Green8)-[:IS_PART_OF]->(Yellow5),
  (Green9)-[:IS_PART_OF]->(Yellow5),
  (Green10)-[:IS_PART_OF]->(Yellow5),
  (Green11)-[:IS_PART_OF]->(Yellow5),
  (Green12)-[:IS_PART_OF]->(Yellow5),
  (Green8)-[:IS_PART_OF]->(Yellow6),
  (Green13)-[:IS_PART_OF]->(Yellow6);

2. Предлагаемое решение:

2.1 Основная идея:

Для желтого узла "это" сравните количество отношений с другим желтым узлом "это" с количеством всех отношений узла "это". Если сумма равна, узел "это" является частью "того".

2.2 Объяснение:

  1. определить все пары между двумя желтыми узлами
  2. определить все зеленые узлы в желто-желтых парах
  3. подсчитайте количество зеленых узлов в желто-желтой паре
  4. определить все взаимосвязи желтого узла под контролем
  5. подсчитайте количество всех взаимосвязей для проверяемого желтого узла
  6. отфильтровать те желто-желтые пары, где количество всех отношений равно количеству парных отношений

2.3 Заявление о шифровании:

//                     |-------------------------------------- (1) ---------------------------------------|
MATCH yellowPairPath = (yellowA:Yellow)<-[pairRelation:IS_PART_OF]-(:Green)-[:IS_PART_OF]->(yellowB:Yellow)
WITH DISTINCT yellowA, yellowB, pairRelation
//            |-------- (2) --------|
WITH yellowA, startNode(pairRelation) AS pairRelations, yellowB
//            |------- (3) ------|
WITH yellowA, count(pairRelations) AS pairRelationAmount, yellowB
//    |---------------------- (4) -----------------------|
MATCH (yellowA:Yellow)<-[allRelations:IS_PART_OF]-(:Green)
//                                |------ (5) ------|
WITH yellowA, pairRelationAmount, count(allRelations) AS allRelationsAmount, yellowB
//      |---------------- (6) ----------------|
  WHERE pairRelationAmount = allRelationsAmount
RETURN yellowA, yellowB;

3. Результат:

Что касается ваших требований, результат должен интерпретироваться как «YellowA является частью YellowB» для перечисленных узлов.

╒═══════════════════╤═══════════════════╕
│"yellowA"          │"yellowB"          │
╞═══════════════════╪═══════════════════╡
│{"name":"Yellow 2"}│{"name":"Yellow 1"}│
├───────────────────┼───────────────────┤
│{"name":"Yellow 3"}│{"name":"Yellow 4"}│
└───────────────────┴───────────────────┘
person ThirstForKnowledge    schedule 21.09.2018
comment
Спасибо @ThirstForKnowledge Почему нам нужно использовать pairRelation и startNode, а затем использовать количество зеленых узлов, а не напрямую использовать, как показано ниже, code MATCH yellowPairPath = (yellowA:Yellow)‹-[pairRelation:IS_PART_OF]-(green:Green)- [:IS_PART_OF]-›(yellowB:Yellow) WITH DISTINCT yellowA, yellowB, pairRelation WITH yellowA, green AS greenNode, yellowB WITH yellowA, count(greenNode) AS pairRelationAmount, yellowB code - person Sreenath S; 24.09.2018
comment
@SreenathS, спасибо за дополнительный запрос! Предлагаемый вами оператор Cypher найдет все пути между двумя желтыми узлами и подсчитает содержащиеся в них зеленые узлы. Он не охватывает возможные дальнейшие зеленые узлы к одному из желтых узлов. В соответствии с вашими требованиями желтый узел является только частью другого желтого узла, если они разделяют все зеленые узлы. Поскольку это сравнение не представлено в предложенном вами заявлении, к сожалению, вы больше не можете идентифицировать какие-либо подпрограммы. Поэтому вам нужны части pairRelation и startNode. - person ThirstForKnowledge; 24.09.2018
comment
Идею моего утверждения Cypher можно резюмировать следующим образом: для желтого узла это сравнивает количество отношений с другим желтым узлом, который с количеством всех отношений узла this. Если количество равно, узел этот является подпунктом этого. - person ThirstForKnowledge; 24.09.2018