Cypher查询具有指定端点的可变长度路径

时间:2018-05-23 14:17:18

标签: neo4j cypher graph-databases

我的图形模型包含有关数据沿袭以及数据如何通过ETL工具中的列映射从一列移动到另一列的信息。基本的一跳模式看起来像这样......

(source:Column)-[:SOURCE_OF_MAPPING]->(map:ColumnMapping)-[:TARGET_OF_MAPPING]->(target:Column)

所以

  • 来源可能是名为" STAGING_TABLE_1.FULL_NAME",
  • 的列
  • 目标可能是名为" STAGING_TABLE_2.FULL_NAME"的列。和
  • 地图将是ETL工具数据流中选择查询中指定的内容。也许类似于" UPPER(STAGING_TABLE_1.FULL_NAME || STAGING_TABLE_1.TITLE)"

我需要做的是说,如果我查看特定目标列,请说" DATA_MART_FACT_1.FULL_NAME",此数据来自哪个列?

以下是我尝试使用的密码查询,但这只会回退一个跃点,即目标为" DATA_MART_FACT_1.FULL_NAME"的源和列映射。

MATCH (source:Column)-[:SOURCE_OF_MAPPING*]->(c:ColumnMapping)-[:TARGET_OF_MAPPING*]->(target:Column)
WHERE target.name = 'DATA_MART_FACT_1.FULL_NAME'
RETURN source, target, c

我试过删除关系名称,只在方括号中加了一个星号,但这只会杀死我的neo4j安装(目前处于5GB内存和50%CPU使用率并且挂起大约10分钟)。所有独特的属性都有限制。

我知道数据包含我需要的内容,因为在neo4j浏览器中我可以扩展节点并按照我希望的那样遵循路径。任何人都可以向我提供一个密码查询,允许我这样做吗?也许我的图形模型在关系名称和方向方面需要一个轻微的重构才能使其工作,我非常乐意探索。

这是一些生成基本示例的密码。

CREATE
(_0:`Column`  {`name`:"STAGING_TABLE_1.FULL_NAME"}),
(_1:`Column`  {`name`:"STAGING_TABLE_2.FULL_NAME"}),
(_2:`Column`  {`name`:"DATA_MART_FACT_1.FULL_NAME"}),
(_3:`ColumnMapping`  {`mappingText`:"UPPER(STAGING_TABLE_1.FULL_NAME)"}),
(_4:`ColumnMapping`  {`mappingText`:"LOWER(STAGING_TABLE_2.FULL_NAME)"}),
(_0)-[:`SOURCE_OF_MAPPING`]->(_3),
(_3)-[:`MAPS_TO`]->(_1),
(_1)-[:`SOURCE_OF_MAPPING`]->(_4),
(_4)-[:`MAPS_TO`]->(_2)

然后我使用的查询只返回一个单跳

MATCH (source:Column)-[:SOURCE_OF_MAPPING*..10]->(c:ColumnMapping)-[:MAPS_TO*..10]->(target:Column) WHERE target.name = 'DATA_MART_FACT_1.FULL_NAME' RETURN source, target, c

然后下一个查询类型返回我之后的内容,但是缺少前两个节点之间的关系。

MATCH (source:Column)-[:SOURCE_OF_MAPPING|MAPS_TO*..10]->(n)-[:MAPS_TO]->(target:Column) 
WHERE target.name = 'DATA_MART_FACT_1.FULL_NAME' 
AND (n:Column or n:ColumnMapping)
RETURN *;

我想从中得到的最终结果如下(注意,此处仅包含别名以说明数据流,并且根据我的要求,实际结果不需要别名)...

(c1:Column)-[:SOURCE_OF_MAPPING]->(cm1:ColumnMapping)-[:MAPS_TO]->(c2:Column)-[:SOURCE_OF_MAPPING]->(cm2:ColumnMapping)-[:MAPS_TO]-(target:Column)

并以表格格式     来源|映射|目标     STAGING_TABLE_1.FULL_NAME | UPPER(STAGING_TABLE_1.FULL_NAME)| STAGING_TABLE_2.FULL_NAME     STAGING_TABLE_2.FULL_NAME |更低(STAGING_TABLE_2.FULL_NAME)| DATA_MART_FACT_1.FULL_NAME

奇怪的是,当我创建一个an interactive example时(该网站可以是片状的,有时可以在它工作之前进行一些刷新),虽然该表按照我的本地安装返回一行,但可视图形表示显示所有期望的节点和关系。

感谢任何建议。提前谢谢。

编辑:我已经重构了我的列映射到目标列关系方向,使流核心自然,好像它是从源,列映射到目标的数据。但是行为没有变化。

2 个答案:

答案 0 :(得分:0)

您可以尝试使用WITH来破解查询,如下:

MATCH (t:Column {name:'DATA_MART_FACT_1.FULL_NAME'})-[:TARGET_OF_MAPPING*]->(c)
WITH t, c 
MATCH (c)-[:SOURCE_OF_MAPPING*]->(s)
RETURN s,t,c

这可以减少笛卡尔产品的情况。我没有尝试过你的情况,但这通常是查看查询的好方法。此外,根据条件修剪脂肪 - 如果:TARGET_OF_MAPPING仅连接到:ColumnMapping,那么您可能不需要指定和测试它。

答案 1 :(得分:0)

对于该示例,以下是如何开始到结尾

MATCH (n)-[:SOURCE_OF_MAPPING|MAPS_TO*..4]->(target:Column) 
WHERE target.name = 'DATA_MART_FACT_1.FULL_NAME' 
AND (n:Column or n:ColumnMapping)
RETURN *;

我怀疑是一个真实的例子,可能有许多连续的列映射,结果可能必须以某种方式聚合,以避免使用开放式可变长度路径杀死性能。