Я пытаюсь сравнить два графика, используя шифр.
Я довольно новичок в Cypher, поэтому не уверен, правильный ли это подход или нет, но если бы я делал это с помощью SQL, я бы использовал запрос NOT IN или MINUS. Я также пытался прочитать плагин алгоритмов графа для neo4j - я подозреваю, что один или несколько из них могут быть полезны, но я действительно не знаю, с чего начать.
Хочу заметить, что у cypher есть операторы UNION и UNION ALL, но нет оператора MINUS, так как мне сделать это в cypher? Опять же, если бы я использовал SQL, я мог бы легко достичь желаемого результата с помощью MINUS.
Во-первых, вот диаграмма моего графика:
В основном это Люди и Части. Люди делают часть. Например, «Боб» делает «роль Боба».
Существует зависимость между частями. Например, «Конечный продукт» состоит из «Партия Боба», «Партия Чарльза» и «Партия Артура».
Наконец, существует зависимость между людьми. В частности, поскольку Питер, который делает конечный продукт, нуждается в деталях от Боба, Артура и Чарльза, у Питера должны быть зависимости от Боба, Артура и Чарльза.
Однако связь между Чарльзом и Питером (показана красным) отсутствует в данных выборки. Это отношения, которые я пытаюсь определить.
Алгоритм, который я использую:
Запрос 1: использование отношения "MADE_FROM", чтобы определить, какие части
раньше делал другую часть. Это график с зелеными вершинами
генерируется из зеленых отношений.
Запрос 2: определите, какие детали используются для изготовления другой детали, следуя
отношения людей и кто что делает. Это (или должно быть)
граф, состоящий из зеленых вершин, но генерируется
следуя отношениям MAKES и DEPENDS_ON.
К сожалению, из-за путаницы отсутствует красное отношение DEPENDS_ON, поэтому результаты двух запросов выше не совпадают.
Ниже приводится пример примечания о данных, что запись Peter,Charles,depends
отсутствует:
id1,id2,relationship
Bob,Bobs Part,makes
Arthur,Arthurs Part,makes
Charles,Charles Part,makes
Peter,Final Product,makes
Peter,Bob,depends
Peter,Arthur,depends
Final Product,Arthurs Part,consists
Final Product,Bobs Part,consists
Final Product,Charles Part,consists
Вот код, который у меня есть, он загружает график из вышеуказанного файла и показывает два запроса, которые я хотел бы использовать с оператором MINUS.
match(p:Person) detach delete p;
match(p:Part) detach delete p;
// Load the parts, people and who makes what relationship (Black relationship).
load csv with headers from 'file:///gmc/relationships.csv' as rec
with rec
where rec.relationship = "makes"
create (person:Person {name: rec.id1})
create (part:Part {partName: rec.id2})
create (person) - [:MAKES] -> (part)
;
// Load the part relationships (green relationships)
load csv with headers from 'file:///gmc/relationships.csv' as rec
with rec
where rec.relationship = "consists"
match (part:Part {partName: rec.id1})
match (madeFrom:Part {partName: rec.id2})
create (part) - [:MADE_FROM] -> (madeFrom)
;
// Load the people dependencies (blue relationships).
load csv with headers from 'file:///gmc/relationships.csv' as rec
with rec
where rec.relationship = "depends"
match (person:Person {name: rec.id1})
match (dependsOn:Person {name: rec.id2})
create (person) - [:DEPENDS_ON] -> (dependsOn)
;
И, наконец, запросы, с которыми я работаю, чтобы создать «Отчет», который мне нужен:
neo4j> // Query1: Produce a list of parts and the parts that they are made from.
neo4j> // i.e. Final Product is made from Arthur's, Bob's and Charles' parts.
neo4j> match(part:Part)-[:MADE_FROM] -> (madeFrom:Part)
return part, madeFrom
order by part.partName, madeFrom.partName;
+--------------------------------------------------------------------------+
| part | madeFrom |
+--------------------------------------------------------------------------+
| (:Part {partName: "Final Product"}) | (:Part {partName: "Arthurs Part"}) |
| (:Part {partName: "Final Product"}) | (:Part {partName: "Bobs Part"}) |
| (:Part {partName: "Final Product"}) | (:Part {partName: "Charles Part"}) |
+--------------------------------------------------------------------------+
3 rows available after 1 ms, consumed after another 0 ms
neo4j> // Query 2: Produce a list of parts and the parts that they are made from
neo4j> // using the Dependencies that the people have on one another.
neo4j> match (part:Part) <- [:MAKES] - (person:Person)-[:DEPENDS_ON] -> (dependsOn:Person)-[:MAKES] -> (madeFrom:Part)
return part, madeFrom
order by part.partName, madeFrom.partName;
+--------------------------------------------------------------------------+
| part | madeFrom |
+--------------------------------------------------------------------------+
| (:Part {partName: "Final Product"}) | (:Part {partName: "Arthurs Part"}) |
| (:Part {partName: "Final Product"}) | (:Part {partName: "Bobs Part"}) |
+--------------------------------------------------------------------------+
2 rows available after 1 ms, consumed after another 0 ms
neo4j> // I need: Query1 MINUS Query2 - which should produce
+--------------------------------------------------------------------------+
| part | madeFrom |
+--------------------------------------------------------------------------+
| (:Part {partName: "Final Product"}) | (:Part {partName: "Charles Part"}) |
+--------------------------------------------------------------------------+
neo4j>
Окончательный набор ответов - это то, что я ищу. Это показывает мне, что «красные отношения» между Питером и Чарльзом отсутствуют, потому что:
- часть, которую делает Питер (Конечный продукт), зависит от части, которую делает Чарльз (Часть Чарльза) Тем не менее,
- они не зависят от Питера до Чарльза по пути "DEPENDS_ON".
Так как я могу сделать это с помощью шифра? Или я полностью лаю не то дерево с таким подходом ????