【问题标题】:Cypher - matching two different possible paths and return bothCypher - 匹配两个不同的可能路径并返回两者
【发布时间】:2015-02-27 14:03:57
【问题描述】:

我有一个数据集,在这里作为示例表示: http://console.neo4j.org/?id=3dq78v

我想要做的是为我的图表中的每个 Z 节点(示例只有一个,但我有很多)我想捕获一组属性,涵盖所有相关的 A、B、C 和 D节点和关系。

我在尝试这样做时遇到了两个问题。第一个是 C 节点连接到 B 节点或 A 节点。其次,D 节点连接到 C 节点,但并不总是存在。

我希望输出一个如下所示的表格:

Z.prop | A.prop | B.prop | (A-B rel).prop | c.prop | (c-d rel).prop | d.prop

我尝试了很多使用 OPTIONAL MATCH 和 WITH 的组合,但我无法得到它。我使用 OPTIONAL MATCH 尝试的所有内容都会找到该匹配项(如果存在),然后不允许我维护与此可选匹配项不匹配的项目(我意识到这是应该做的)。如果有帮助,我可以分享我尝试过的更具体的查询。

任何见解都会很棒!

编辑:使用版本 Neo4j 2.0.3 编辑:更新了控制台链接并进行了小修正

这是我尝试过的一个查询。我意识到为什么这不起作用,但也许你可以看到我的“逻辑”我希望可选匹配不删除节点,如果它们不匹配,如果它找到一些匹配。我想要那些不匹配和做的。

MATCH (z:Z)-[:has]->(a:A)
OPTIONAL MATCH (a)-[:has*1..2]->(c:C)
OPTIONAL MATCH (a)-[:has]->(b:B)-[:CONTAINS]->(c)
OPTIONAL MATCH (c)-[cd:knows]->(d:D)
RETURN z.name, a.name, b.name, c.name, d.name, cd.score;

编辑:我想做的是使用下面 4 个查询的结果,但使用 1 个查询得到结果

#1
MATCH (z:Z)-[:has]->(a:A)
MATCH (A)-[mr:has]->(b:B)-[:has]->(c:C)
MATCH (c)-[ds:knows]->(d:d)
RETURN  a.name, b.name, mr.order, c.name, d.name, ds.score;

#2
MATCH (z:Z)-[:has]->(a:A)
MATCH (A)-[mr:has]->(b:B)-[:has]->(c:C)
WHERE NOT (c)-[:knows]->(:d)
RETURN a.name, mr.order, b.name, c.name;

#3
MATCH (z:Z)-[:has]->(a:A)
MATCH (A)-[:has]->(c:C)
WHERE NOT (c)-[:knows]->(:d)
RETURN  a.name, c.name;

#4
MATCH (z:Z)-[:has]->(a:A)
MATCH (A)-[:has]->(c:C)
MATCH (c)-[ds:knows]->(d:d)
RETURN a.name, c.name, d.name, ds.score;

尽管有些结果,但这些并没有按我预期的方式工作。例如,我希望查询 3 只返回:

A2  C4  d4  8
A2  C4  d5  6
A2  C4  d6  9

编辑 - 我的目标是精确输出:

a.name  mr.order b.name c.name  d.name  d.score
A1      1        B3
A1      2        B1     C2
A1      2        B1     C5
A1      2        B1     C1      d1      1
A1      2        B1     C1      d3      4
A1      2        B1     C1      d2      3
A2      1        B4
A2      2        B2     C3
A2                      C4      d4      8
A2                      C4      d5      6
A2                      C4      d6      9

这与我正在寻找的 11 行中的 9 行匹配,它错过了 B3 和 B4 行

MATCH (z:Z)-[:has]->(a:A)
WITH a, z
MATCH (a)-[*1..2]-(c:C)
OPTIONAL MATCH (a)-[mr:has]->(b:B)-[:has]-(c:C)
WITH a, b, c, z, mr
OPTIONAL MATCH (c)-[cd:knows]->(d:d)
RETURN z.name, a.name, mr.order, b.name, c.name, d.name, cd.score;

【问题讨论】:

  • 您确实需要分享您的查询;完全不清楚你在这里真正想要做什么。
  • 我添加了一些我尝试过的查询。

标签: neo4j cypher


【解决方案1】:

不完全确定您对输出的期望,但这个可能有效:

MATCH (z:Z)-[:has]->(a:A)
WITH a, z
MATCH (b:B), (a)-[*1..2]-(c:C)
WHERE (a)-[:has]->(b)-[:CONTAINS]->(c) OR (a)-[:has*1..2]->(c)
WITH a, b, c, z
OPTIONAL MATCH (c)-[cd:knows]->(d:d)
RETURN z.name, a.name, b.name, c.name, d.name, cd.score;

你可以从那里优化它。

编辑 在您添加之后,我认为唯一实现这一目标的方法是使用两个查询的 UNION

MATCH (a:A)-[mr:has]->(b:B)
OPTIONAL MATCH (b)-->(c:C)
OPTIONAL MATCH (c)-[cd]->(d:d)
RETURN a.name, mr.order, b.name, c.name, d.name, cd.score
UNION
MATCH (a:A)-[mr:has]->(c:C)
OPTIONAL MATCH (c:C)-[cd]->(d:d)
OPTIONAL MATCH (b:B)-->(c:C)
RETURN a.name, mr.order, b.name, c.name, d.name, cd.score

请注意,在UNION 之后的第二个查询中,OPTIONAL MATCH (b:B)-->(c:C) 只是为了使UNION 成为可能,因为 Neo4j 不允许只返回空字符串而不是 b.name。好消息是UNION 将删除重复项,从而产生预期的结果。

a.name  mr.order    b.name  c.name  d.name  cd.score
A1      1           B3          
A1      2           B1      C5      
A1      2           B1      C1      d1      1
A1      2           B1      C1      d2      4
A1      2           B1      C1      d3      3
A1      2           B1      C2      
A2      1           B4          
A2      2           B2      C3      
A2                          C4      d4      8
A2                          C4      d5      6
A2                          C4      d6      9
Showing 1 to 11 of 11 entries

查询耗时 9 毫秒,返回 11 行。

【讨论】:

  • 我更新了控制台,我意识到我还需要从与 (B) 的传入关系中捕获一个属性。有了这个,我不能在 WHERE 子句中添加标识符。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 1970-01-01
  • 2013-04-18
  • 2023-03-04
  • 2012-07-12
相关资源
最近更新 更多