根据上游节点过滤属性过滤Neo4J中的传入节点

时间:2018-08-27 19:14:04

标签: neo4j cypher

在处理rdbms数据沿袭项目时,我面临无法解决的Neo4J Cypher挑战:

这是示例:

  1. 图由代表数据库表(标签: TABLE )或视图(标签: VIEW )的节点组成
  2. 表或其他视图通过方向-[:SOURCES]-> 关系
  3. 获得视图 图的一个子集具有10个TABLE节点,这些节点可以选择进行过滤(从图中排除)。通过名称属性将它们命名为A1到A10。这些节点具有附加标签 FILTERNODE
  4. 这10个节点通过SOURCES关系链接到VIEW节点B, example A1-[:SOURCES]-> B
  5. 节点B依次查看VIEW节点C: B-[:SOURCES]-> C
  6. 节点C具有用于过滤的数组属性: C.filter = ['A2','A3']
  7. 节点C依次查看VIEW节点D: B-[:SOURCES]-> C

现在,我想查询从A *节点到D的链,不显示所有A *节点,而是仅显示那些由节点C的filter属性过滤的节点。

我想这需要分多个步骤完成:

  1. 首先选择整个子图,其中包含A1..A10,B,C,D
  2. 然后从该子图中唯一地收集所有过滤属性
  3. 在具有FILTERNODE属性的节点上使用收集的过滤属性,仅保留A2,A3,B,C和D

我如何在Cypher中完成此操作?

2 个答案:

答案 0 :(得分:1)

这里是密码reference card;但基本上,您想从属性中收集多个数组,将它们组合成一个列表,然后将其用作过滤器。将所有内容组合到一个列表中所需的主要功能是EXTRACT + REDUCE,并带有一个过滤器来保护自己免受空值(未设置属性)的影响。

这里是一个Cypher,显示了如何作为一个干净的步骤进行提取+还原,并附有注释,解释了Cypher的每一步。

// Match our starting point, and collect all child views (0.. collects itself too)
MATCH (:TABLE)-[:SOURCES]->(start:View)-[:SOURCES*0..25]->(view:View)
// Make sure we only have one copy of each view
WITH COLLECT(DISTINCT view) as views
// Collect all filters (if they exist) into one list
WITH views, reduce(s = [], v IN [x IN views WHERE EXISTS(x.filter) | x.filter]| s + v.filter) as filters
// Match all tables in filter list
MATCH (a:TABLE)
WHERE a.name IN filters
// Format return; Everything in one column
WITH views+COLLECT(a) as ns
UNWIND ns as n
RETURN n

答案 1 :(得分:0)

因此,您是从特定的C节点开始的,需要遍历并获取:TABLE节点作为源,但仅限那些由C上的list属性过滤的节点。

这应该有效:

number      num_fives
000000000   2
545678910   1

如果您有很多输入节点,并且:TABLE(name)是唯一的,那么我们可以对其进行修改以在可能的输入节点上进行预匹配,从而让我们进行节点比较而不是属性比较:

MATCH (c)
WHERE id(c) = 123 // standin for however you match to your starting node
WITH c, c.filter as allowed
MATCH (a:TABLE)-[:SOURCES*]->(c)
WHERE a.name in allowed
RETURN a