Neo4j:匹配多个标签(2个或更多)

cl25kdpy  于 2022-10-21  发布在  其他
关注(0)|答案(7)|浏览(416)

我想做一个搜索,我想从2个标签(或条件)开始遍历。例如,我需要找出标签为‘Male’或‘Female’并且其属性name=~‘.ail.’的所有节点。

ijnw1ujt

ijnw1ujt1#

您可以将此条件放在WHERE子句中:

MATCH (n)
WHERE n:Male OR n:Female
RETURN n

编辑

正如@tbaum指出的那样,这将执行一个AllNodesScan。我在标签相当新的时候编写了答案,并期望查询规划器最终为每个标签使用NodeByLabelScan来实现它,就像它对单个标签的情况一样

MATCH (n)
WHERE n:Male
RETURN n

我仍然认为这是查询的合理表达,并且期望查询规划器使用标签扫描来实现它是合理的,但是在Neo4j 2.2.3中,查询仍然是使用AllNodesScan和标签过滤器来实现的。因此,这里有一个更冗长的替代方案。由于标签析取表示集合并集,并且该并集可以用不同的方式表示,因此我们可以用一种查询规划器无需扫描所有节点就可以实现的方式来表示它,而是以每个标签的NodeByLabelScan开始。

MATCH (n:Male)
WHERE n.name =~ '.ail.'
RETURN n
UNION MATCH (n:Female)
WHERE n.name =~ '.ail.'
RETURN n

这意味着为每个标签表示一次查询,并使用显式的UNION连接它们。这并不是不合理的,至少对于较少数量的标签是这样的,但是我不清楚为什么查询规划者不能从更简单的查询中推断出相同的实现,所以我打开了GitHub问题here

5vf7fwbs

5vf7fwbs2#

MATCH n WHERE n:Label1 OR n:Label2

..。将导致AllNodesScan,这不是一个好主意!
也许有一个更好的解决方案:

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)
enyaitl3

enyaitl33#

在Neo4j 3.4.7中,当您向查询规划器提交一个带有2个OR标签过滤器的WHERE查询时,它会先执行UNION,然后执行DISTINCT。尝试将sandbox Offshore Leaks DatabaseEXPLAIN MATCH (o) WHERE o:Officer OR o:Entity RETURN o一起使用会产生以下计划:

7nbnzgx9

7nbnzgx94#

如果要使用OR或IN条件按多个标签过滤节点,请使用以下代码:

MATCH (n)
WHERE labels(n) in [['Male'],['Female']]
AND n.name =~ '.ail.'
RETURN n
s8vozzvw

s8vozzvw5#

至于v3.5,我们可以做:

MATCH (n) WHERE (n:User OR n:Admin) AND n.name CONTAINS "ail" RETURN n

并获得:

╒══════════════════╕
│"n"               │
╞══════════════════╡
│{"name":"Abigail"}│
├──────────────────┤
│{"name":"Bailee"} │
└──────────────────┘
3j86kqsm

3j86kqsm6#

另一种选择是,如果您需要使用组合集或以其他方式避免使用UNION:

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;

这种方法不如Union方法高效,但仍然避免了昂贵的AllNodesScan操作符。在我的用例中,查询已经包含了一个用于不同目的的UNION。

gorkyyrv

gorkyyrv7#

V3.0的文档中这样写道:
还可以描述具有多个标签的节点:
(a:User:Admin)-->(b)
消息来源:https://neo4j.com/docs/developer-manual/current/cypher/#_labels

相关问题