Получить все подграфы определенного типа в Neo4J - PullRequest
0 голосов
/ 21 сентября 2018

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

![enter image description here

Узлы в желтом связаны зелеными узлами с помощью отношения "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», поскольку не имеет общих зеленых узлов.

Ответы [ 2 ]

0 голосов
/ 21 сентября 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 Основная идея:

Для желтого узла "this" сравните количество отношений с другим желтым узлом "that" с количеством all отношения узла "это".Если сумма равна, узел «this» является подразделом «that».

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

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

2.3 Оператор Cypher:

//                     |-------------------------------------- (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"}│
└───────────────────┴───────────────────┘
0 голосов
/ 21 сентября 2018

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

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

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
...