继承与关系的节点属性到另一个节点其在Neo4j的孩子(Inherit properties from

2019-09-28 10:12发布

继承所有的家长性能。

考虑我有以下格式的图形。 我想一个节点的属性(这将是在帐户节点,如果它有一个关系)由其子节点继承。 假设父母和子女节点关系由保持[R:CHILD]和帐户信息由[R2:ACCOUNT]。 如果节点有多个父,它需要从它与第一个帐户的所有继承父:

       (a0:ACCOUNT)<-[:HAS_ACCOUNT]-Morpheus
                                     \
         (a1:ACCOUNT)<-[:HAS_ACCOUNT]-Neo
                                       \
                                       alpha    
                                        \ 
                                       gamma    beta - [:HAS_ACCOUNT]->(a2:ACCOUNT)
                                          \    /
                                            A 
                                          /   \
            (a3:ACCOUNT)<-[:HAS_ACCOUNT]-B     C
                                       /  \   /  \
                                      D    E  F   G

我想提取从上面的图是这样的数据:

问题:给定一个节点,得到它的所有儿童以及其帐户(如果它有帐户,如:见节点B)或其继承帐户信息。 ACCOUNTID的帐户节点的一部分

考虑输入是节点A

OUTPUT:

|Node | CurrentNode|     Account   |Inherited_Account|
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    A       |     -         |   a1.accountID ,| 
|     |            |               |   a2.accountID  |
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    B       |  a3.accountID |        -        | 
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    D       |               |    a3.accountID | 
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    E       |               |    a3.accountID | 
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - -
|  A  |    C       |               |   a1.accountID ,| 
|     |            |               |   a2.accountID  |
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    F       |               |   a1.accountID ,| 
|     |            |               |   a2.accountID  |
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 
|  A  |    G       |               |   a1.accountID ,| 
|     |            |               |   a2.accountID  |
 - - - - - -- - - - - -- - - - - -- - - - - -- - - - - 

这是我的暗号以检索,我想出了,让我所有的家长的所有帐户。 它不工作有时

MATCH (node:Person{personID:"A"})
MATCH (account:ACCOUNT)
MATCH p =(parent:Person)-[:CHILD*1..]->(node)
where (parent)-[:HAS_ACCOUNT]->(account)
UNWIND RELATIONSHIPS(p) AS rel 
WITH p, account, COUNT(DISTINCT rel) AS nRoutes 
RETURN account,p, nRoutes 
ORDER BY nRoutes

Answer 1:

这是一个棘手的一个。

纯的Cypher溶液存在,但它是一个复杂的查询,并且需要一些潜在的重滤波来清除路径以考虑保持,超出沿着相同的路径更靠近帐户保持节点的节点。

然而,我发现使用Cypher和更好的替代APOC的路径扩展 ,再加上添加一个标签是账户持有人节点的一些预处理。

APOC的路径膨胀机具有扩大同时尊重标签滤波器的装置,以及有定义哪些应修剪任何进一步的遍历,但被包括作为溶液中的标签的装置。 我们将用这个节点获得帐户持有的祖先时限制我们的扩张。

这里有一个创建的查询重新创建您的示例图(虽然我标记非户口节点为:节点):

// create inherited account graph
create (morpheus:Node{name:'Morpheus'})
create (neo:Node{name:'Neo'})
create (alpha:Node{name:'alpha'})
create (gamma:Node{name:'gamma'})
create (beta:Node{name:'beta'})

create (A:Node{name:'A'})
create (B:Node{name:'B'})
create (C:Node{name:'C'})
create (D:Node{name:'D'})
create (E:Node{name:'E'})
create (F:Node{name:'F'})
create (G:Node{name:'G'})

create (morpheus)-[:CHILD]->(neo)
create (neo)-[:CHILD]->(alpha)
create (alpha)-[:CHILD]->(gamma)
create (gamma)-[:CHILD]->(A)
create (beta)-[:CHILD]->(A)
create (A)-[:CHILD]->(B)
create (A)-[:CHILD]->(C)
create (B)-[:CHILD]->(D)
create (B)-[:CHILD]->(E)
create (C)-[:CHILD]->(F)
create (C)-[:CHILD]->(G)

create (morpheus)-[:HAS_ACCOUNT]->(a0:ACCOUNT{name:'a0'})
create (neo)-[:HAS_ACCOUNT]->(a1:ACCOUNT{name:'a1'})
create (beta)-[:HAS_ACCOUNT]->(a2:ACCOUNT{name:'a2'})
create (B)-[:HAS_ACCOUNT]->(a3:ACCOUNT{name:'a3'})

接下来,我们标注的开户节点。

MATCH (acc:ACCOUNT)
WITH acc
MATCH (acc)<-[:HAS_ACCOUNT]-(holder)
SET holder:ACCOUNT_HOLDER

一旦这项工作到位,我们可以使用下面的查询,以获得您想要的输出:

// parameterize this in your own query
with 'A' as nodeName
match (node:Node{name:nodeName})-[r:CHILD*0..]->(currentNode)
with node, currentNode, size(r) as distance
optional match (currentNode)-[:HAS_ACCOUNT]->(acc)
with node, currentNode, distance, collect(acc) as accounts
// we now have all child nodes of the given node and their accounts, if they exist.

// this expands up from each currentNode, 
// stopping each expansion at the closest ACCOUNT_HOLDER node
call apoc.path.expand(currentNode, '<CHILD', '/ACCOUNT_HOLDER', -1, -1)
yield path
with node, currentNode, distance, accounts, last(nodes(path)) as holder
// get the account for each holder, 
// but only if the current doesn't have its own accounts
optional match (holder)-[:HAS_ACCOUNT]->(acc)
where size(accounts) = 0
with node, currentNode, accounts, collect(acc) as inherited, distance
order by distance asc
return node, currentNode, accounts, inherited

但是,请注意,即使使用这种方法,查询不会建立和重用的解决方案(例如,一旦我们找到了节点A的帐户持有的祖先,这种解决方案不被引用或再利用时,我们必须让帐户增加保持的祖先节点,C,F,或G)。 你可能要考虑一个自定义的过程在代码执行这个复杂的匹配操作,而不是Cypher支架的最大效率。



文章来源: Inherit properties from a node with relationship to another node to its child in neo4j