OPTIONAL MATCH (n1:Label1)
WITH collect(distinct n1) as c1
OPTIONAL MATCH (n2:Label2)
WITH collect(distinct n2) + c1 as c2
OPTIONAL MATCH (n3:Label3)
WITH collect(distinct n3) + c2 as c3
UNWIND c3 as nodes
RETURN count(nodes),labels(nodes)
在Neo4j 3.4.7中,当您向查询规划器提交一个带有2个OR标签过滤器的WHERE查询时,它会先执行UNION,然后执行DISTINCT。尝试将sandbox Offshore Leaks Database与EXPLAIN MATCH (o) WHERE o:Officer OR o:Entity RETURN o一起使用会产生以下计划:
MATCH(m:Male) WHERE m.name=~'.ail.' WITH COLLECT(m) AS male
MATCH(f:Female) WHERE f.name=~'.ail.' WITH male, COLLECT(f) AS female
UNWIND (male + female) AS person
RETURN person.name;
7条答案
按热度按时间ijnw1ujt1#
您可以将此条件放在
WHERE
子句中:编辑
正如@tbaum指出的那样,这将执行一个
AllNodesScan
。我在标签相当新的时候编写了答案,并期望查询规划器最终为每个标签使用NodeByLabelScan
来实现它,就像它对单个标签的情况一样我仍然认为这是查询的合理表达,并且期望查询规划器使用标签扫描来实现它是合理的,但是在Neo4j 2.2.3中,查询仍然是使用
AllNodesScan
和标签过滤器来实现的。因此,这里有一个更冗长的替代方案。由于标签析取表示集合并集,并且该并集可以用不同的方式表示,因此我们可以用一种查询规划器无需扫描所有节点就可以实现的方式来表示它,而是以每个标签的NodeByLabelScan
开始。这意味着为每个标签表示一次查询,并使用显式的
UNION
连接它们。这并不是不合理的,至少对于较少数量的标签是这样的,但是我不清楚为什么查询规划者不能从更简单的查询中推断出相同的实现,所以我打开了GitHub问题here。5vf7fwbs2#
..。将导致AllNodesScan,这不是一个好主意!
也许有一个更好的解决方案:
enyaitl33#
在Neo4j 3.4.7中,当您向查询规划器提交一个带有2个OR标签过滤器的WHERE查询时,它会先执行UNION,然后执行DISTINCT。尝试将sandbox Offshore Leaks Database与
EXPLAIN MATCH (o) WHERE o:Officer OR o:Entity RETURN o
一起使用会产生以下计划:7nbnzgx94#
如果要使用OR或IN条件按多个标签过滤节点,请使用以下代码:
s8vozzvw5#
至于v3.5,我们可以做:
并获得:
3j86kqsm6#
另一种选择是,如果您需要使用组合集或以其他方式避免使用UNION:
这种方法不如Union方法高效,但仍然避免了昂贵的AllNodesScan操作符。在我的用例中,查询已经包含了一个用于不同目的的UNION。
gorkyyrv7#
V3.0的文档中这样写道:
还可以描述具有多个标签的节点:
(a:User:Admin)-->(b)
消息来源:https://neo4j.com/docs/developer-manual/current/cypher/#_labels