我试图找出如何返回包含以下内容的结果集:
-
父/子类型节点,子节点与父节点具有相同的标签,因此是主结果中的有效项
-
但如果将Child节点作为"child"匹配包含在内,则应将其从主结果中排除
-
如果父项不包含子项,则应将其排除在主要结果之外
我可以得到这个主要是工作,但我不能让第三点工作令人满意 .
我的查询类似于以下内容(已删除不相关的过滤):
MATCH (f:Fruit),(tof:TypeOfFruit)
WITH f, tof
MATCH (f)-[:IS_BANANA|IS_APPLE]->(tof)
WHERE NOT (tof)<-[:IS_APPLE]-(f)<-[:IN_FRUIT_SALAD]-()
OPTIONAL MATCH (tof)<-[:IS_BANANA]-(f)-[r:IN_FRUIT_SALAD]->(f1:Fruit)-[:IS_APPLE]->(tof)
WITH DISTINCT f, COLLECT(DISTINCT f1) AS f1
RETURN { fruit : f, fruitSaladComponents : f1 }
所以我想回来:
-
香蕉是苹果水果沙拉的一部分
-
不属于香蕉水果沙拉的苹果
-
"children"用香蕉制作水果沙拉的苹果
但是由于可选的匹配,这个查询返回的香蕉不是苹果水果沙拉的一部分 .
我认为可能有一种方法可以做到这一点涉及Collection FILTER
ing,但我无法使它工作 .
我已经尝试将此作为 UNION
(并使用 MATCH
而不是 OPTIONAL MATCH
),这可能是我最接近的结果,但是由于 UNION
中的每个查询都是原子的,我最终不得不重复逻辑另一个查询,我认为必须有一种方法来做到这一点,没有 UNION
.
我真的对Cypher解决方案感兴趣而不是建模解决方案,但很高兴听到任何想法 .
链接到NEO4J控制台:http://console.neo4j.org/?id=x03foa
在那里你会看到 UNION
查询返回我想要使用 UNION
的结果,因为有条件我需要根据 UNION
的第一部分的结果进行过滤加上我不想要添加一个新的 UNION
每次我添加一个新的水果和香蕉不会永远是"parent" ...等等 -
MATCH (f:Fruit),(tof:TypeOfFruit)
WITH f, tof
MATCH (tof)<-[:IS_BANANA]-(f)-[:IN_FRUIT_SALAD]->(f1:Fruit)-[:IS_APPLE]->(tof)
WITH DISTINCT f, COLLECT(DISTINCT f1) AS f1
RETURN { fruit : f, fruitSaladComponents : f1 }
UNION
MATCH (f:Fruit),(tof:TypeOfFruit)
WITH f, tof
MATCH (f)-[:IS_APPLE]->(tof)
WHERE NOT (f)<-[:IN_FRUIT_SALAD]-()
WITH DISTINCT f,[] AS f1
RETURN { fruit : f, fruitSaladComponents : f1 }
更新26/05/2015:
以下查询有效,但有没有更好的方法 - 即 WHERE
和后续 OPTIONAL MATCH
没有重复?
MATCH (f:Fruit),(tof:TypeOfFruit)
WITH f, tof
MATCH (f)-[:IS_BANANA|IS_APPLE]->(tof)
WHERE ((tof)<-[:IS_BANANA]-(f)-[:IN_FRUIT_SALAD]->(:Fruit)-[:IS_APPLE]->(tof)) OR ((tof)<-[:IS_APPLE]-(f) AND NOT (f)<-[:IN_FRUIT_SALAD]-())
OPTIONAL MATCH (tof)<-[:IS_BANANA]-(f)-[r:IN_FRUIT_SALAD]->(f1:Fruit)-[:IS_APPLE]->(tof)
WITH DISTINCT f, COLLECT(DISTINCT f1) AS f1
RETURN { fruit : f, fruitSaladComponents : f1 }
1 回答
解决方案与上面一样(稍微改动以移动WHERE子句) -
如果有人知道更好的解决方案,请告知 .