我正在尝试使用cypher比较两个图。
我对cypher还是很陌生,所以不确定是否正确的方法,但是如果我要使用SQL进行此操作,我将使用NOT IN或MINUS查询。我还尝试阅读了neo4j的图形算法插件-我怀疑其中的一个或多个可能会有所帮助,但是我真的不知道从哪里开始。
我注意到cypher具有UNION和UNION ALL运算符,但没有MINUS运算符,那么我将如何在cypher中执行此操作?同样,如果我使用SQL,则可以使用MINUS轻松实现所需的结果。
首先,这是我的图表:
基本上有人员和零件。人们参与其中。例如,“鲍勃”就是“鲍勃的角色”。
各部分之间存在依赖性。例如,“最终产品”是由“鲍勃的零件”,“查尔斯的零件”和“亚瑟的零件”制成的。
最后,人与人之间存在依赖性。特别是由于生产最终产品的彼得需要鲍勃,亚瑟和查尔斯的零件,因此彼得应该对鲍勃,亚瑟和查尔斯有依赖性。
但是,样本数据中缺少Charles和Peter之间的关系(以红色显示)。这是我要确定的关系。
我正在使用的算法是:
查询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>
最终的答案是我要寻找的。这表明我彼得和查尔斯之间的“红色关系”缺失了,因为:
那么我该如何使用密码呢?还是我完全用这种方法吠叫了错误的树??
答案 0 :(得分:2)
从SQL切换到Cypher时需要注意一些步骤。尽量少考虑“表”,而多考虑“关系”。它需要做一些事情,但是当它单击时,一切开始变得更加明显。
此查询将为您提供想要的信息:
match (m:Person)-[:MAKES]->(x:Part)-[:MADE_FROM]->(y:Part)<-[:MAKES]-(n:Person)
where not (m)-[:DEPENDS_ON]-(n)
return m,x,y,n
基本上,它会寻找一个人m
,该人制造的零件x
由零件y
制成,零件n
由人m
制造,其中{ {1}}未连接到n
。查询的编写方式确保m
和n
是不同的人,并且x
和y
是不同的部分。
这些类型的自反“联接”在SQL中是一场噩梦,但在Cypher中相对容易。