我有一个简化的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.
感谢您的任何帮助!
答案 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