neo4j是否有减号运算符

时间:2019-05-13 07:59:15

标签: neo4j cypher

我正在尝试使用cypher比较两个图。

我对cypher还是很陌生,所以不确定是否正确的方法,但是如果我要使用SQL进行此操作,我将使用NOT IN或MINUS查询。我还尝试阅读了neo4j的图形算法插件-我怀疑其中的一个或多个可能会有所帮助,但是我真的不知道从哪里开始。

我注意到cypher具有UNION和UNION ALL运算符,但没有MINUS运算符,那么我将如何在cypher中执行此操作?同样,如果我使用SQL,则可以使用MINUS轻松实现所需的结果。

首先,这是我的图表:

Diagram of my sample data

基本上有人员和零件。人们参与其中。例如,“鲍勃”就是“鲍勃的角色”。

各部分之间存在依赖性。例如,“最终产品”是由“鲍勃的零件”,“查尔斯的零件”和“亚瑟的零件”制成的。

最后,人与人之间存在依赖性。特别是由于生产最终产品的彼得需要鲍勃,亚瑟和查尔斯的零件,因此彼得应该对鲍勃,亚瑟和查尔斯有依赖性。

但是,样本数据中缺少Charles和Peter之间的关系(以红色显示)。这是我要确定的关系。

我正在使用的算法是:

  1. 查询1:使用“ MADE_FROM”关系来确定哪些部分是 用来制造另一部分。这是带有绿色顶点的图 从绿色关系生成。

  2. 查询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> 

最终的答案是我要寻找的。这表明我彼得和查尔斯之间的“红色关系”缺失了,因为:

    彼得制造的(最终产品)部分取决于查尔斯制造的部分(查尔斯的部分)。但是,
  • 他们从Peter到Charles都不依赖“ DEPENDS_ON”路径。

那么我该如何使用密码呢?还是我完全用这种方法吠叫了错误的树??

1 个答案:

答案 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。查询的编写方式确保mn是不同的人,并且xy是不同的部分。

这些类型的自反“联接”在SQL中是一场噩梦,但在Cypher中相对容易。