【问题标题】:does neo4j have a minus operatorneo4j 有减号运算符吗
【发布时间】:2019-05-13 07:59:15
【问题描述】:

我正在尝试使用密码比较两个图表。

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

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

首先,这是我的图表:

基本上有人物和部分。人们制造一个零件。例如,“Bob”成为“Bob 的一部分”。

各部分之间存在依赖关系。例如,“最终产品”由“Bob's Part”、“Charles' Part”和“Arthur's Part”组成。

最后,人与人之间存在依赖。具体来说,由于制造最终产品的 Peter 需要 Bob、Arthur 和 Charles 的零件,因此 Peter 应该依赖 Bob、Arthur 和 Charles。

但是,示例数据中缺少 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 制造的零件(Charles 的零件)。然而,
  • 他们不依赖于“DEPENDS_ON”路径上从 Peter 到 Charles。

那么我该如何使用 cypher 来做到这一点?还是我用这种方法完全找错了树????

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    从 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 制作,其中 m 未连接到 @987654327 @。查询的编写方式确保mn 是不同的人,xy 是不同的部分。

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

    【讨论】:

    • mn 仍然可能是同一个人/节点。您可以在 WHERE 子句中添加 AND m &lt;&gt; n 以确保它们不是。
    • 谢谢 Marj,这似乎有效。实际上,当我之前在 SQL 中完成此(问题)时,它相对容易 - 我想它归结为您所知道的,或者在这种情况下是我以前不知道的。 :-)
    • 好点猎鹰。我对你的评论投了赞成票。但是,我认为当前模式不会发生这种情况,除非同一个人制作两个部分,其中一个是由另一个组成的,否则除非该人与自己有 :DEPENDS_ON 关系,否则他们会被挑选出来。
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2023-03-18
    相关资源
    最近更新 更多