我想遍历neo4j中的PATH(最好使用Cypher,但我可以编写neo4j托管扩展)。
问题- 对于任何起始节点(:Person),我都想遍历
之类的层次结构(我:人)-[:朋友|:知识*]->(新人:人)
如果存在:FRIEND外向关系,则路径应遍历该路径,并忽略任何:KNOWS外向关系;如果:FRIEND关系不存在,但:KNOWS关系存在,则PATH应该遍历该节点。
现在,上面语法的问题是它同时返回了带有:FRIEND和:KNOWS的路径-我无法根据上述要求滤除特定方向。
答案 0 :(得分:1)
为便于进一步解答和解决方案,我注意到了我的图形创建语句:
CREATE
(personA:Person {name:'Person A'})-[:FRIEND]->(personB:Person {name: 'Person B'}),
(personB)-[:FRIEND]->(personC:Person {name: 'Person C'}),
(personC)-[:FRIEND]->(personD:Person {name: 'Person D'}),
(personC)-[:FRIEND]->(personE:Person {name: 'Person E'}),
(personE)-[:FRIEND]->(personF:Person {name: 'Person F'}),
(personA)-[:KNOWS]->(personG:Person {name: 'Person G'}),
(personA)-[:KNOWS]->(personH:Person {name: 'Person H'}),
(personH)-[:KNOWS]->(personI:Person {name: 'Person I'}),
(personI)-[:FRIEND]->(personJ:Person {name: 'Person J'});
MATCH (startNode:Person {name:'Person A'})
OPTIONAL MATCH friendPath = (startNode)-[:FRIEND*]->(:Person)
OPTIONAL MATCH knowsPath = (startNode)-[:KNOWS*]->(:Person)
RETURN friendPath, knowsPath;
如果您不需要到达整个路径的所有节点的每个路径,而只需要整个路径,那么出于性能原因,我建议使用shortestPath()。
请注意缺少的节点“ Person J”,因为它与节点“ Person I”具有FRIENDS
关系。
或者,您可以使用Expand paths的APOC user library函数。根据过程的下一步,您可以在节点,关系或两者的标识之间进行选择。
MATCH (startNode:Person {name:'Person A'})
CALL apoc.path.subgraphNodes(startNode,
{maxLevel: -1, relationshipFilter: 'FRIEND>', labelFilter: '+Person'}) YIELD node AS friendNodes
CALL apoc.path.subgraphNodes(startNode,
{maxLevel: -1, relationshipFilter: 'KNOWS>', labelFilter: '+Person'}) YIELD node AS knowsNodes
WITH
collect(DISTINCT friendNodes.name) AS friendNodes,
collect(DISTINCT knowsNodes.name) AS knowsNodes
RETURN friendNodes, knowsNodes;
startNode
)上的给定关系(relationshipFilter: 'FRIEND>'
)从给定的labelFilter: '+Person'
展开。startNode
)上的给定关系(relationshipFilter: 'KNOWS>'
)从给定的labelFilter: '+Person'
展开。FRIEND
关系类型聚合所有节点(如果需要完整的节点,请省略.name
部分)KNOWS
关系类型聚合所有节点(如果需要完整的节点,请省略.name
部分)╒═════════════════════════════════════════════╤═════════════════════════════════════════════╕
│"friendNodes" │"knowsNodes" │
╞═════════════════════════════════════════════╪═════════════════════════════════════════════╡
│["Person A","Person B","Person C","Person E",│["Person A","Person H","Person G","Person I"]│
│"Person D","Person F"] │ │
└─────────────────────────────────────────────┴─────────────────────────────────────────────┘
答案 1 :(得分:0)
MATCH p = (me:Person)-[:FRIEND|:KNOWS*]->(newPerson:Person)
WITH p, extract(r in relationships(p) | type(r)) AS types
RETURN p ORDER BY types asc LIMIT 1
答案 2 :(得分:0)
这是询问每个节点的传出关系的类型,然后根据一些嵌套的案例逻辑优先确定要保留哪些关系的问题。
使用上面的小图
MATCH path = (a)-[r:KNOWS|FRIEND]->(b)
WITH a, COLLECT([type(r),a,r,b]) AS rels
WITH a,
rels,
CASE WHEN filter(el in rels WHERE el[0] = "FRIEND") THEN filter(el in rels WHERE el[0] = "FRIEND")
ELSE CASE WHEN filter(el in rels WHERE el[0] = "KNOWS") THEN filter(el in rels WHERE el[0] = "KNOWS") ELSE [''] END END AS search
UNWIND search AS s
RETURN s[1] AS a, s[2] AS r, s[3] AS b
我相信这会返回您的预期结果:
根据您的逻辑,不应从人A到人G或人H遍历,因为从人A到人B的朋友关系优先。
但是,由于存在奇异的KNOWS关系,因此从人H到人I进行遍历,然后又从人I到人J进行遍历。