【问题标题】:Neo4j: Take intersection of two MATCHsNeo4j:取两个 MATCH 的交集
【发布时间】:2021-11-25 01:26:59
【问题描述】:

我有以下两个疑问:

MATCH (s1: location)-[:SHIPS_TO]->(: midLocation)-[: LEAVES]->(d1: location)
RETURN s1.name, count(d1)
MATCH (s2: location)-[:SHIPS_TO]->(: midLocation)-[: LEAVES]->(d2: location)
WHERE s2.manager = d2.manager 
RETURN s2.name, count(d2)

我想做的是返回这两个查询的交集。但我似乎找不到实现它的方法。也许这是另一种方法?

【问题讨论】:

  • 如果我错了,请纠正我,但看起来查询是一样的,只是您在最后一个中添加了WHERE s2.manager = d2.manager?如果是这样,那么两者的交集就是第二个查询的结果。
  • 不,抱歉。我想要一份所有地点的列表,这些地点只运送到同一个经理的地点。所以查询只会计算这个条件成立的位置的数量。例如,如果一个位置 loc1 被运送到 4 个地方,其中 3 个具有相同的经理,那么第一个查询将返回“loc1:4”,第二个查询将返回“loc1:3”。然后,该交叉点将是该位置运送到的所有位置都具有相同的经理。如果两个查询的计数相同,我只想返回位置。

标签: neo4j intersection


【解决方案1】:

如果你有一个谓词集合,你可以使用all 来检查它们是否都是真的,所以你可以这样做

MATCH (s1: location)-[:SHIPS_TO]->(: midLocation)-[: LEAVES]->(d1: location)
WITH s1, collect(DISTINCT d1) AS destinations
WHERE all(d IN destinations WHERE d.manager = s1.manager)
RETURN s1.name, size(destinations)

这将过滤掉具有与其目标不同的经理的任何源位置。 请注意,这不是最佳选择,因为在检查它们是否具有相同的经理之前,您仍然会找到每个位置对。最好找到一种方法,让第一个匹配语句在找到另一个经理的目的地后立即失败,但我认为这在纯 Cypher 中是不可能的。

【讨论】:

  • 谢谢!这确实返回了正确的位置!但是当我运行它时它说 d1 没有定义?
  • 对,这是最后一行出错了。d1 不再定义,因为它不是从 with 语句中进行的。我已经在修复中进行了编辑。
猜你喜欢
  • 2016-02-29
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多