密码-匹配两个不同的可能路径并返回两者 [英] Cypher - matching two different possible paths and return both
问题描述
我有一个数据集,在这里以示例的方式表示:
http:/ /console.neo4j.org/?id=3dq78v
I have a a data set that I have represented here as an example: http://console.neo4j.org/?id=3dq78v
我想要做的是针对图形中的每个Z节点(该示例只有一个但我有很多)我想捕获一组涵盖所有关联的A,B,C和D节点和关系的属性。
What I am trying to do is for every Z node in my graph (the example only has one but I have many) I want to capture a set of properties that cover all all of the associated A, B, C and D nodes and relationships.
我遇到了试图做到这一点的两个问题。首先是C节点连接到B节点或A节点。第二个D节点连接到C节点,但并不总是存在。
I have come across two issues trying to do this. The first is that the C nodes are either connected to the to the B nodes OR the A nodes. Second the D nodes are connected to C nodes but not always present.
我要输出一个看起来像这样的表:
I am looking to output a table that looks something like this:
Z.prop | A.prop | B.prop | (A-B rel).prop | c.prop | (c-d rel).prop | d.prop
Z.prop | A.prop | B.prop | (A-B rel).prop | c.prop | (c-d rel).prop | d.prop
我尝试了很多使用OPTIONAL MATCH和WITH的组合,但我无法做到。我使用OPTIONAL MATCH尝试过的所有内容都会找到该匹配项(如果存在),然后不允许我维护与该可选匹配项不匹配的项目(这是我应该做的)。我可以分享我尝试过的更具体的查询是否有帮助。
I have tried a lot of combinations of using OPTIONAL MATCH and using WITH but I can not get it. Everything I have tried with OPTIONAL MATCH will find that match if it exists and then not allow me to maintain the items that did not match this optional match (Which I realize is what it is supposed to do). I can share more specific queries I have tried if that will help.
任何洞察力都很好!
编辑:使用Neo4j 2.0.3版本
编辑:使用较小的更正更新了控制台链接
using version Neo4j 2.0.3 updated console link with a small correction
这是我尝试过的查询。我了解了为什么这行不通,但是也许您可以看到我的逻辑,我希望可选匹配项在发现某些匹配项时不删除不匹配的节点。我想要那些不匹配的东西。
Here is a query I have tried. I realize why this doesn't work, but maybe you can see my 'logic' I want the optional match to not remove nodes if they dont match if it finds some matches. I want the ones that dont match and do.
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个查询
What I am trying to do is use the results from the 4 queries below but get the results with 1 query
#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仅返回:
These don't work the way I was expecting though because some results. For example I was expecting query 3 to only return:
A2 C4 d4 8
A2 C4 d5 6
A2 C4 d6 9
编辑-精确输出我的目标是:
EDIT - EXACT output I am aiming for:
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的行
This matches 9 of the 11 lines I am looking for, it misses the lines with B3 and 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;
推荐答案
不确定作为输出的期望,但这可能会起作用:
Not completely sure about what you would expect as the ouput, but this one might work:
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;
从那里可以对其进行优化。
From there you could optimize it.
编辑
添加后,我认为唯一的实现方法是使用两个查询的 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
,可选匹配(b:B)->(c:C)
仅用于生成 UNION
是可能的,因为Neo4j不允许只返回一个空字符串而不是 b.name
。好消息是 UNION
将删除重复项,因此会得到预期的结果。
Note that in the second query after the UNION
, the OPTIONAL MATCH (b:B)-->(c:C)
is only there to make the UNION
possible, since Neo4j doesn't allow to just return an empty string instead of b.name
. The good news is that UNION
will remove duplicates, therefore resulting in the expected result.
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行。
Query took 9 ms and returned 11 rows.
这篇关于密码-匹配两个不同的可能路径并返回两者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!