匹配仅与特定节点有关系的节点

时间:2018-10-02 10:12:18

标签: neo4j cypher

我希望返回仅与其他特定作业使用相同工具的节点列表。

我的节点是作业,这些作业与也是节点的工具具有需求关系。

如果我匹配特定的工作,例如建造一个棚子,然后建造一个棚子,则需要使用锤子,螺丝刀和锯子。其他哪些工作仅需要在建造棚子时需要的工具(包括需要这些工具的任意组合的工作,甚至只要该工作不需要其他工具即可),例如,建造围栏需要使用锤子和锯子,因此应将其退还,但是拆除棚屋即使需要使用锤子也不应返回,因为它也需要撬棍。

现在我有

Match (j:Job{Title: 'Build Shed'}) - [:Requires] -> (t:tools)
Match (o:otherJob) - [:Requires] -> (t)
return j,o,t

但是,这将返回所有需要使用任何这些工具的工作,即使这些工作还需要建造棚子不需要的其他工具。

1 个答案:

答案 0 :(得分:1)

您可能想查看performing match intersection的Cypher知识库条目。

也就是说,本文将帮助您找到需要以前匹配的所有工具的工作,但是您需要做更多的工作以确保工作所需的工具数量准确无误。您正在使用的工具数量。

这里是一个示例,当从工具扩展到需要它们的作业时,使用第一种方法来计算匹配数:

MATCH (j:Job{Title: 'Build Shed'}) - [:Requires] -> (t:tools)
WITH collect(t) as tools, count(t) as requiredToolCount
UNWIND tools as t // change back to rows
MATCH (o:otherJob) - [:Requires] -> (t)
WITH o, tools, requiredToolCount, count(t) as toolsRequired
WHERE toolsRequired = requiredToolCount AND toolsRequired = size((o)-[:REQUIRES]->())
RETURN o, tools

这里的想法是,我们收集必需的工具并获得它们的数量(因此,例如,锤子,螺丝刀和锯子,所以这是3种必需的工具的数量。

然后,我们将集合展开成行,并从工具扩展到需要该工具的作业。然后我们进行汇总,因此对于每个工作,我们都会获得与该工作相匹配的3种工具的数量。我们只希望保留匹配的那些工具的数量=所需工具的数量的作业,因此在本例中,我们只希望保留具有3个匹配项的工作(每个这些工具1个)。

最后,我们检查了该工作所需的工具总数,并确保该数量等于我们感兴趣的工具数量(因为如果数量更多,那么该工作所需的工具就会比我们正在考虑的更多。

编辑

有其他要求,我们还希望找到可能使用的工具数量少于开始工作时要匹配的工具总数,但前提是不需要其他工具。这是我们修改查询的方法:

MATCH (j:Job{Title: 'Build Shed'}) - [:Requires] -> (t:tools)
WITH collect(t) as tools, count(t) as maxRequiredToolCount
UNWIND tools as t // change back to rows
MATCH (o:otherJob) - [:Requires] -> (t)
WITH o, tools, maxRequiredToolCount, count(t) as toolsRequired
WHERE toolsRequired <= maxRequiredToolCount AND toolsRequired = size((o)-[:REQUIRES]->())
RETURN o, tools