使用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
可以做得更好吗?
答案 0 :(得分:1)
不确定一般情况,但对于这种特定情况,您可能会尝试将两种模式合并为一种,如下所示:
MATCH (u:User{username:'squirrel'})<-[:MEMBER*0..1]-()-[:KNOW_HOW]->(k:Knowledge)
RETURN k.type
答案 1 :(得分:1)
到目前为止我找到的唯一通用解决方案:
现在代码本身:
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