0

我是 Neo4j 的新手,并试图通过实现用于企业参考/集成架构的图形数据库(将所有企业应用程序显示为节点、基础表/API 的架构 - 逻辑分组为节点、应用程序之间的集成为关系)来做 POC。

目标是利用 Graph DB 的优势无缝地实现“影响分析”(注意:我理解这可能是实现目标的不正确方法,因此欢迎提出建议)

现在让我简要介绍一下我的问题,

有四个应用程序 - A1、A2、A3、A4;A1 有一组表(由节点 A1TS1 表示)由集成 1(在本例中为关系)更新,并且集成 2 读取同一组表。因此数据模型如下所示

(A1TS1)<-[:INT1]-(A1)<-[:INT1]-(A2)
(A1TS1)-[:INT2]->(A1)-[:INT2]->(A4)

我将底层应用程序表名称捕获为 A1TS1 节点中的 List 属性。

假设其中一个应用表已针对新列或数据类型进行了更改,我想了解所有受影响的集成和应用程序。现在我正在尝试编写如下查询来检索由于此表更改而关联/影响的所有节点和关系,但我无法实现这一点

预期结果是 - 所有受影响的节点(A1TS1、A1、A2、A4)和关系(INT1、INT2)

选项 1(使用 APOC)

MATCH (a {TCName:'A1TS1',AppName:'A1'})-[r]-(b) 
WITH a as STRTND, Collect(type(r)) as allr 
CALL apoc.path.subgraphAll(STRTND, {relationshipFilter:allr}) YIELD nodes, relationships 
RETURN nodes, relationships

这失败并出现错误Failed to invoke procedure 'apoc.path.subgraphAll': Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String

选项 2(使用 with、unwind、collect 子句)

MATCH (a {TCName:'A1TS1',AppName:'A1'})-[r]-(b) 
WITH a as STRTND, Collect(r) as allr 
UNWIND allr as rels 
MATCH p=()-[rels]-()-[rels]-() 
RETURN p

这失败并出现错误“不能对多个模式使用相同的关系变量'rels'”但是如果我使用 [rels] 一次就像p=()-[rels]=()它一样工作但没有产生所有节点

任何帮助/建议/领导表示赞赏。提前致谢

更新 尝试提供更多上下文 显示基础数据

MATCH (TC:TBLCON) RETURN TC

"TC"
{"Tables":["TBL1","TBL2","TBL3"],"TCName":"A1TS1","AppName":"A1"}  
{"Tables":["TBL4","TBL1"],"TCName":"A2TS1","AppName":"A2"} 

MATCH (A:App) RETURN A

"A"                                                                   
{"Sponsor":"XY","Platform":"Oracle","TechOwnr":"VV","Version":"12","Tags":["ERP","OracleEBS","FinanceSystem"],"AppName":"A1"}               
{"Sponsor":"CC","Platform":"Teradata","TechOwnr":"RZ","Tags":["EDW","DataWarehouse"],"AppName":"A2"}   

MATCH ()-[r]-() RETURN distinct r.relname

"r.relname"
"FINREP"   │  (runs between A1 to other apps)
"UPFRNT"   │  (runs between A2 to different Salesforce App)
"INVOICE"  │  (runs between A1 to other apps)

有了这个,这就是我试图实现的假设“TBL3”在 App A1 中被更改,我想编写一个查询以匹配模式指定表“TBL3”,获取所有关联的关系和连接的节点(上游)

可能我需要分 3 步实现,第 1 步 - 编写匹配模式以查找起始节点和关联关系第 2 步 - 将第 1 步中的关系存储在数组变量/参数中 第 3 步 - 通过第 1 步的起始节点和第 2 步的参数到 apoc.path.subgraphAll 以查看所有受影响的节点

这在概念上听起来可能是有效的,但如何在 neo4j Cypher 查询中技术上做到这一点是个问题。

希望这可以帮助

4

2 回答 2

0

此查询可能会执行您想要的操作:

MATCH (tc:TBLCON)
WHERE $table IN tc.Tables
MATCH p=(tc)-[:Foo*]-()
WITH tc,
  REDUCE(s = [], x IN COLLECT(NODES(p)) | s + x) AS ns,
  REDUCE(t = [], y IN COLLECT(RELATIONSHIPS(p)) | t + y) AS rs
UNWIND ns AS n
WITH tc, rs, COLLECT(DISTINCT n) AS nodes
UNWIND rs AS rel
RETURN tc, nodes, COLLECT(DISTINCT rel) AS rels;

它假定您提供感兴趣的表的名称(例如,“TBL3”)作为table 参数的值。它还假设感兴趣的关系都具有Foo类型。

它首先找到包含该表名tcTBLCON节点。然后,它使用可变长度非定向搜索来搜索所有路径(具有非重复关系),其中包括tc. 然后它使用COLLECT两次:聚合每个路径中的节点列表,以及聚合每个路径中的关系列表。每个聚合结果将是一个列表列表,因此它REDUCE在每个外部列表上使用以合并内部列表。然后它在每个列表上使用UNWINDandCOLLECT(DISTINCT x)来生成具有唯一元素的列表。

[更新]

如果您按类型(而不是按属性值)区分您的关系,则通过利用 APOC 函数,您的 Cypher 代码可以简单得多。以下查询假定所需的关系类型是通过types参数传递的:

MATCH (tc:TBLCON)
WHERE $table IN tc.Tables
CALL apoc.path.subgraphAll(
  tc, {relationshipFilter: apoc.text.join($types, '|')}) YIELD nodes, relationships
RETURN nodes, relationships;
于 2018-02-01T03:32:26.813 回答
0

在cybersam的回应中,下面的查询让我得到了我想要的东西。唯一的限制是,此结果仅限于 3 层(通过可选匹配的第 3 层)

MATCH (TC:TBLCON) WHERE 'TBL3' IN TC.Tables 
CALL apoc.path.subgraphAll(TC, {maxLevel:1}) YIELD nodes AS invN, relationships AS invR
WITH TC, REDUCE (tmpL=[], tmpr IN invR | tmpL+type(tmpr)) AS impR
MATCH FLP=(TC)-[]-()-[FLR]-(SL) WHERE type(FLR) IN impR 
WITH FLP, TC, SL,impR 
OPTIONAL MATCH SLP=(SL)-[SLR]-() WHERE type(SLR) IN impR RETURN FLP,SLP

这适用于我的需要,希望这也可以帮助某人。

谢谢大家的回复和建议

****更新****

增强了查询以摆脱可选匹配条件和其他给定限制

MATCH (initTC:TBLCON) WHERE $TL IN initTC.Tables 
WITH Reduce(O="",OO in Reduce (I=[], II in collect(apoc.node.relationship.types(initTC)) | I+II) | O+OO+"|") as RF
MATCH (TC:TBLCON) WHERE $TL IN TC.Tables 
CALL apoc.path.subgraphAll(TC,{relationshipFilter:RF}) YIELD nodes, relationships
RETURN nodes, relationships

谢谢大家(尤其是cybersam)

于 2018-02-01T18:33:25.760 回答