过滤两个密码路径上的节点

时间:2016-11-10 09:18:00

标签: neo4j pattern-matching cypher

我有一个简化的Neo4j图形(旧版本2.x)作为具有“定义”和“相同”边缘的图像。假设<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <index>false</index> <manifest> <packageName>com.batch.cilabo</packageName> <mainClass>org.springframework.batch.core.launch.support.CommandLineJobRunner</mainClass> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <configuration> <finalName>BBBB01</finalName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>org.springframework.batch.core.launch.support.CommandLineJobRunner</Main-Class> <Class-Path>./</Class-Path> <Build-Number>1</Build-Number> </manifestEntries> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer"> <resource>.properties</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> </transformers> <archive> <manifestEntries> <Class-Path>./</Class-Path> </manifestEntries> </archive> </configuration> <version>1.7</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 边上的数字是边缘上的属性

我想要运行的查询是:

1)通过A和B查找节点define - 需要的结果:C,C,D

defined

以上工作并返回C和D.但是我想要C两次,因为它定义了两次。但是如果没有x上的distinct,它将返回从A到B的所有路径。

2)查找NOT的节点(由A,B OR定义,由A,B定义,但通过同一边连接) - 必需结果:G

类似的东西:

START A=node(885), B=node(996) MATCH (A-[:define]->(x)<-[:define]-B) RETURN DISTINCT x

R1: MATCH (A-[:define]->(x)<-[:define]-B) RETURN DISTINCT x

(由A - (R1 + R2)定义的节点)

3)找到A和B都没有匹配调用的“中间”节点 - 需要的结果:C,G

我想输出C,因为1 R2: MATCH (A-[:define]->(e)-(:similar)-(f)<-[:define]-B) RETURN e,f(45/46)没有来自B的匹配定义。 同时输出G,因为B中没有define到G. enter image description here

感谢您的任何帮助!

1 个答案:

答案 0 :(得分:1)

你的语法对我来说有点奇怪,所以我假设你使用的是旧版本的Neo4j。不过,我们应该可以使用相同的方法。

对于#1,你提议的匹配没有明显应该是有效的。我唯一能看到的是在A和B节点变量周围添加缺少的括号。

START A=node(885), B=node(996) 
MATCH (A)-[:define]->(x)<-[:define]-(B) 
RETURN x

另外,我不确定你的意思是“返回从A到B的所有路径”。你能澄清一下吗,并提供一个输出的例子吗?

对于#2,我们需要几个部分来进行此查询,并相应地将它们与WITH分开。

START A=node(885), B=node(996) 
MATCH (A)-[:define]->(x)<-[:define]-(B)
WITH A, B, COLLECT(DISTINCT x) as exceptions
OPTIONAL MATCH (A)-[:define]->(x)-[:same]-(y)<-[:define]-(B)
WHERE x NOT IN exceptions AND y NOT IN exceptions
WITH A, B, exceptions + COLLECT(DISTINCT x) + COLLECT(DISTINCT y) as allExceptions
MATCH (aNode)
WHERE aNode NOT IN allExceptions AND aNode <> A AND aNode <> B
RETURN aNode

此外,您应该在节点上使用标签。最终匹配将匹配图表中的所有节点,否则必须进行过滤。

修改

关于你的#3要求,SIZE()函数在这里非常有用,因为你可以得到模式匹配的大小,它会告诉你该模式的出现次数。

此查询的方法是首先获取由A或B定义的节点集合,然后向下过滤到节点,其中数量:定义来自A的关系不等于以下数量:定义来自B的关系。

虽然我们想使用类似UNION WITH的东西来获得A定义的节点的并集并将它与B定义的节点联合起来,但Neo4j的UNION支持现在很弱,因为它不会让你在UNION发生之后执行任何其他操作,因此我们不得不求助于将两组节点添加到同一个集合中,然后将它们展开回行。

START A=node(885), B=node(996) 
MATCH (A)-[:define]->(x)
WITH A, B, COLLECT(x) as middleNodes
MATCH (B)-[:define]->(x) 
WITH A, B, middleNodes + COLLECT(x) as allMiddles
UNWIND allMiddles as middle
WITH DISTINCT A, B, middle
WHERE SIZE((A)-[:define]->(middle)) <> SIZE((B)-[:define]->(middle))
RETURN middle