简体   繁体   English

有没有办法使用Cypher遍历neo4j Path以获得不同的关系

[英]Is there a way to Traverse neo4j Path using Cypher for different relationships

I want to Traverse a PATH in neo4j (preferably using Cypher, but I can write neo4j managed extensions). 我想在neo4j中遍历PATH(最好使用Cypher,但我可以编写neo4j托管扩展)。

Problem - For any starting node (:Person) I want to traverse hierarchy like 问题 - 对于任何起始节点(:Person),我想遍历层次结构,如

(me:Person)-[:FRIEND|:KNOWS*]->(newPerson:Person) (我:人) - [:朋友|:KNOWS *] - >(newPerson:人)

if the :FRIEND outgoing relationship is present then the path should traverse that, and ignore any :KNOWS outgoing relationships, if :FRIEND relationship does not exist but :KNOWS relationship is present then the PATH should traverse that node. 如果:FRIEND传出关系存在,那么路径应该遍历那个,并忽略任何:KNOWS传出关系,如果:FRIEND关系不存在但是:KNOWS关系存在,那么PATH应该遍历该节点。

Right now the problem with above syntax is that it returns both the paths with :FRIEND and :KNOWS - I am not able to filter out a specific direction based on above requirement. 现在上面语法的问题是它返回两个路径:FRIEND和:KNOWS - 我无法根据上述要求过滤掉特定方向。

1. Example data set 1.示例数据集

For the ease of possible further answers and solutions I note my graph creating statement: 为了便于进一步解答和解决方案,我注意到我的图表创建语句:

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'});

图1

2. Scenario "Optional Match" 2.场景“可选匹配”

2.1 Solution 2.1解决方案

MATCH (startNode:Person {name:'Person A'})
OPTIONAL MATCH friendPath = (startNode)-[:FRIEND*]->(:Person)
OPTIONAL MATCH knowsPath = (startNode)-[:KNOWS*]->(:Person)
RETURN friendPath, knowsPath;

If you do not need every path to all nodes of the entire path, but only the whole, I recommend using shortestPath() for performance reasons. 如果您不需要遍历整个路径的所有节点的每条路径,而只需要整个路径,我建议使用shortestPath()以提高性能。

2.1 Result 2.1结果

Note the missing node 'Person J', because it owns a FRIENDS relationship to node 'Person I'. 注意缺少的节点'Person J',因为它拥有与节点'Person I'的FRIENDS关系。

图2

3. Scenario "Expand paths" 3.场景“展开路径”

3.1 Solution 3.1解决方案

Alternatively you could use the Expand paths functions of the APOC user library . 或者,您可以使用APOC用户库的“ 扩展路径”功能。 Depending on the next steps of your process you can choose between the identification of nodes, relationships or both. 根据流程的后续步骤,您可以选择节点,关系或两者的标识。

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;

3.2 Explanation 3.2解释

  • line 1: defining your start node based on the name 第1行:根据名称定义起始节点
  • line 2-3: Expand from the given startNode following the given relationships ( relationshipFilter: 'FRIEND>' ) adhering to the label filter ( labelFilter: '+Person' ). 第2-3行:在给定的关系( relationshipFilter: 'FRIEND>' )之后从给定的startNode扩展,粘贴到标签过滤器( labelFilter: '+Person' )。
  • line 4-5: Expand from the given startNode following the given relationships ( relationshipFilter: 'KNOWS>' ) adhering to the label filter ( labelFilter: '+Person' ). 第4-5行:在给定的关系( relationshipFilter: 'KNOWS>' )之后从给定的startNode扩展,粘贴到标签过滤器( labelFilter: '+Person' )。
  • line 7: aggregates all nodes by following the FRIEND relationship type (omit the .name part if you need the complete node) 第7行:按照FRIEND关系类型聚合所有节点(如果需要完整节点,则省略.name部分)
  • line 8: aggregates all nodes by following the KNOWS relationship type (omit the .name part if you need the complete node) 第8行:按照KNOWS关系类型聚合所有节点(如果需要完整节点,则省略.name部分)
  • line 9: render the resulting groups of nodes 第9行:渲染结果节点组

3.3 Result 3.3结果

╒═════════════════════════════════════════════╤═════════════════════════════════════════════╕
│"friendNodes"                                │"knowsNodes"                                 │
╞═════════════════════════════════════════════╪═════════════════════════════════════════════╡
│["Person A","Person B","Person C","Person E",│["Person A","Person H","Person G","Person I"]│
│"Person D","Person F"]                       │                                             │
└─────────────────────────────────────────────┴─────────────────────────────────────────────┘
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

This is a matter of interrogating the types of outgoing relationships for each node and then making a prioritized decision on which relationships to retain leveraging some nested case logic. 这是询问每个节点的传出关系的类型,然后对哪些关系保留利用某些嵌套的案例逻辑做出优先级决定的问题。

Using the small graph above 使用上面的小图

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

I believe this returns your expected result: 我相信这会返回您的预期结果:

在此输入图像描述

Based on your logic, there should be no traversal to Person G or Person H from Person A, as there is a FRIEND relationship from Person A to Person B that takes precedence. 根据您的逻辑,不应该从人员A遍历人员G或人员H,因为从人员A到人员B的FRIEND关系优先。

However there is a traversal from Person H to Person I because of the existence of the singular KNOWS relationship, and then a subsequent traversal from Person I to Person J. 然而,由于存在单一的KNOWS关系,然后随后从人I到人J的遍历,从人H到人I的遍历。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM