将来自更多MATCH的节点组合成单个变量

时间:2014-03-07 00:23:56

标签: neo4j cypher

使用neo4j社区版2.x.在Cypher中,我需要以(两种)不同方式匹配节点,然后将这两组匹配的节点组合成单个集合(一个变量名称)。然后将该集合用于进一步的行动。

naive graph example(我无法发布图片)

我想找到所有关于松鼠的知识,包括她所属团体所分享的知识。 (例子是虚构的)

我想象这样的事情:

MATCH (u:User{username:'squirrel'}), (:User{username:'squirrel'})<-[:MEMBER]-(g:Group)
WITH "COMBINATION OF u AND g" AS ug
MATCH (ug)-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type

结果应该是“破解坚果”和“逃避掠夺者”。

在“你和你的组合”的地方我尝试了收集(你)+收集(g),提取等的变化。没有成功。

到目前为止,我找到的最简单的工作方式是使用UNION。

MATCH (u:User{username:'squirrel'})-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type
UNION
MATCH (u:User{username:'squirrel'})<-[:MEMBER]-(:Group)-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type

这可能会解决这个简单的例子,但不适合更复杂的查询。我寻求更普遍问题的解决方案:匹配几组节点,将它们粘合到单个集合(单个变量)中并继续使用这个新集合。

请问任何想法?我错过了什么基本的东西?或者这不可能吗?谢谢!

grokbase上可能有类似内容。

修改

使用this hacky solution to similar question我能够通过从节点集合中提取内部ID来解决问题:

MATCH (u:User{username:'squirrel'}), (:User{username:'squirrel'})<-[:MEMBER]-(g:Group)
WITH [x in collect(u)+collect(g)|id(x)] as collectedIds MATCH (ug) WHERE id(ug) in collectedIds
MATCH (ug)-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type

可以做得更好吗?

3 个答案:

答案 0 :(得分:1)

不确定一般情况,但对于这种特定情况,您可能会尝试将两种模式合并为一种,如下所示:

MATCH (u:User{username:'squirrel'})<-[:MEMBER*0..1]-()-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type

答案 1 :(得分:1)

到目前为止我找到的唯一通用解决方案:

  • 匹配所需的起点(使用不同的名称)
  • 收集起点的内部ID
  • 将起点与收集的ID匹配(现在起点有单个名称)
  • 对起点进行任何操作

现在代码本身:

MATCH (u:User{username:'squirrel'}), (:User{username:'squirrel'})<-[:MEMBER]-(g:Group)
WITH [x in collect(u)+collect(g)|id(x)] as collectedIds MATCH (ug) WHERE id(ug) in collectedIds
MATCH (ug)-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type

答案 2 :(得分:1)

至少从Neo4j 3.0开始,您可以使用可变长度模式匹配来解决此问题。只需将最小长度显式设置为0,然后将标签测试移动到单独的WHERE子句:

MATCH (:User {username:'squirrel'}) <-[:MEMBER*0..1]- (ug)
WHERE ug:User OR ug:Group
WITH ug
MATCH (ug)-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type