Je voudrais faire une recherche, et je voudrais commencer à parcourir à partir de 2 étiquettes (condition OR). Par exemple, j'ai besoin de trouver tous les nœuds qui ont des étiquettes 'Male' ou 'Female' et dont la propriété, name = ~ '.ail.'.
Vous pouvez mettre cela dans la clause WHERE
:
MATCH n
WHERE n:Male OR n:Female
RETURN n
[~ # ~] modifier [~ # ~]
Comme le souligne @tbaum, cela effectue un AllNodesScan
. J'ai écrit la réponse lorsque les étiquettes étaient assez nouvelles et je m'attendais à ce que le planificateur de requêtes l'implémente finalement avec un NodeByLabelScan
pour chaque étiquette, comme il le fait pour le cas d'une seule étiquette
MATCH n
WHERE n:Male
RETURN n
Je pense toujours que c'est une expression raisonnable de la requête et qu'il est raisonnable de s'attendre à ce que le planificateur de requêtes l'implémente avec des analyses d'étiquettes, mais à partir de Neo4j 2.2.3, la requête est toujours implémentée avec un AllNodesScan
et un filtre d'étiquette. Voici donc une alternative plus verbeuse. Étant donné que la disjonction d'étiquettes signifie une union définie et que cette union peut être exprimée de différentes manières, nous pouvons l'exprimer d'une manière que le planificateur de requêtes implémente sans analyser tous les nœuds, et commence à la place par un NodeByLabelScan
par étiquette.
MATCH (n:Male)
WHERE n.name =~ '.ail.'
RETURN n
UNION MATCH (n:Female)
WHERE n.name =~ '.ail.'
RETURN n
Cela signifie exprimer la requête une fois pour chaque étiquette et les joindre avec un UNION
explicite. Ce n'est pas déraisonnable, du moins pour un plus petit nombre d'étiquettes, mais je ne comprends pas pourquoi les planificateurs de requêtes ne devraient pas pouvoir déduire la même implémentation à partir de la requête plus simple, j'ai donc ouvert un problème de github ici .
MATCH n WHERE n:Label1 OR n:Label2
... se traduira par un AllNodesScan c'est une mauvaise idée!
peut-être une meilleure solution:
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)
Avec Neo4j 3.4.7, le planificateur de requêtes effectue un UNION puis un DISTINCT de 2 NodeByLabelScan
s lorsque vous lui passez une requête WHERE avec 2 filtres d'étiquette OR. Essayer la Sandbox Offshore Leaks Database avec EXPLAIN MATCH (o) WHERE o:Officer OR o:Entity RETURN o
donne cette planification: