【问题标题】:OPTIONAL MATCH returns no path for disconnect nodesOPTIONAL MATCH 不返回断开节点的路径
【发布时间】:2017-12-10 11:10:50
【问题描述】:

我觉得奇怪的是,使用不具有预期关系的 OPTIONAL MATCH 节点不会作为路径中的单个节点返回。

OPTIONAL MATCH path = (:Person) -[:LIKES]- (:Movie) 
UNWIND nodes(p) as n 
UNWIND rels(p) as e 
WITH n 
WHERE HEAD(LABELS(n)) = “Person” 
return COUNT(DISTINCT n)

返回的人数仅包括喜欢电影的人数。通过使用 OPTIONAL,我预计所有人都会被退回。 是否有解决方法或者我在查询中做错了什么?

【问题讨论】:

  • 我应该补充说问题是由于 UNWIND rels()
  • UNWIND 生成行,如果 UNWIND 没有生成行,则不会进一步。

标签: neo4j cypher


【解决方案1】:

解决此问题的更好方法是首先匹配所有 :People 节点,然后使用 OPTIONAL MATCH 匹配电影(或者,如果您想要他们喜欢的电影的集合,请使用 pattern comprehension)。

如果您确实需要在不清除行的情况下对空集合执行 UNWIND,请在某些条件周围使用 CASE 以使用单元素列表而不是空列表。

MATCH (n:Person)   // match all persons
OPTIONAL MATCH p = (n) -[:LIKES]- (m:Movie) // p and m are the optionals
UNWIND CASE WHEN p is null THEN [null] ELSE nodes(p) END as nodes  // already have n, using a different variable
UNWIND CASE WHEN p is null THEN [null] ELSE rels(p) END as e // forcing a single element list means UNWIND won't wipe out the row
WITH n 
WHERE HEAD(LABELS(n)) = “Person”  // not really needed at all, and bad practice, you don't know the order of the labels on a node
return COUNT(DISTINCT n) // if this is really all you need, just keep the first match and the return of the query (without distinct), don't need anything else

【讨论】:

  • 太棒了!我从来没有想过为此使用 CASE,现在看起来很明显。确实我需要使用 UNWIND 与其他人一起返回起始节点。
  • 因为除非图中没有人,否则 p 不能为空,我将您的提案更改为 UNWIND CASE WHEN length(p) = 0 THEN [null] ELSE Relations(p) END as e。
  • 我的p 位置与您的不同。它在我们已经匹配到 n 之后处于 OPTIONAL MATCH 上,因此当一个人不喜欢电影时它可以为空。
  • 是不是因为你在可选匹配之前以 match (n:Person) 开头?
  • 是的。这确保n 将匹配所有 :Person 节点。 OPTIONAL MATCH 不会改变这一点,但如果图中没有与该模式匹配,则该 OPTIONAL MATCH 中新引入的变量(pm)将为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-18
  • 2020-11-19
  • 1970-01-01
  • 2018-04-06
  • 2021-09-19
  • 1970-01-01
相关资源
最近更新 更多