2013-11-15 22 views

Odpowiedz

29

można umieścić, że w klauzuli WHERE:

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

EDIT

Jak @tbaum wskazuje na to wykonuje AllNodesScan. Napisałem odpowiedź kiedy etykiety były dość nowy i oczekuje planista zapytania ostatecznie wdrożyć go z NodeByLabelScan dla każdej etykiety, jak ma to miejsce w przypadku pojedynczej etykiecie

MATCH n 
WHERE n:Male 
RETURN n 

nadal uważam, że jest to rozsądne wyrażenie z zapytanie i rozsądne jest oczekiwać, że terminarz zaimplementuje go ze skanowaniem etykiet, ale od Neo4j 2.2.3 kwerenda jest nadal implementowana z AllNodesScan i filtrem etykiet. Oto zatem bardziej gadatliwa alternatywa. Ponieważ rozdzielenie etykiety oznacza zbiór związków, a to połączenie może być wyrażone na różne sposoby, możemy wyrazić je w taki sposób, w jaki planer zapytań wdraża bez skanowania wszystkich węzłów, a zamiast tego zaczyna się od NodeByLabelScan dla każdej etykiety.

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

Oznacza to, wyrażając zapytanie raz dla każdej etykiety i łącząc je z wyraźną UNION. Nie jest to nieuzasadnione, przynajmniej dla mniejszej liczby etykiet, ale nie jest dla mnie jasne, dlaczego planiści zapytań nie powinni móc wywnioskować tej samej implementacji z prostszego zapytania, więc otworzyłem numer github here.

+8

Czy jest to krótszy sposób? Dla np. dla relacji możesz podać '(n) - [: rel1 | rel2] -> (m) 'gdzie' | 'oznacza' OR' –

+0

Nie, nie możesz użyć tego wzoru dla etykiet i nie jestem świadomy żadnego innego wzoru, który jest krótszy lub działa bez klauzuli WHERE. Możesz przesłać żądanie funkcji w Neo4j [repozytorium github] (https://github.com/neo4j/neo4j/issues). – jjaderberg

+0

@Lyman Zerga również szukałem w wielu miejscach, ale nie mając nic takiego –

9
MATCH n WHERE n:Label1 OR n:Label2 

... spowoduje, że AllNodesScan to zły pomysł!

może lepszym rozwiązaniem:

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) 
+1

Dlaczego potrzebujesz "różnych" na każdym kroku? –

+0

Dzięki za wskazanie 'AllNodesScan', pomyślałem, że do tej pory zostałby rozwiązany. Zaktualizowałem swoją odpowiedź, czy masz jakieś przemyślenia na temat mojej bardziej szczegółowej alternatywy używając 'UNION' i jak to się porównuje do' OPCJONALNEJ MECZ'/'collect()'/'UNWIND'? – jjaderberg

+1

Jedna uwaga: UNION jest niewygodny (i w niektórych przypadkach nieużyteczny), ponieważ obecnie (2.2) nie można wykonać żadnego przetwarzania z wynikami UNION. Na przykład nie możesz użyć SKIP/LIMIT lub COUNT. –

-2

Dokumentacja v3.0 mówi tak:

Można również opisać węzeł, który ma wielu etykiet:

(a:User:Admin)-->(b)

Źródło: https://neo4j.com/docs/developer-manual/current/cypher/#_labels

+0

Odpowiedź jest niepoprawna, ale nie jest całkowicie zła, myślę, że autor właśnie pominął, aby uwzględnić relację w zapytaniu, ale działa w celu dopasowania wielu etykiet węzłów: 'MATCH (a: Użytkownik: Admin) - [ r] -> (b) zwraca a, r, b' – artemisian

+0

FYI. Adres URL źródła nieco się zmienił. To jest nowe: https://neo4j.com/docs/developer-manual/current/cypher/syntax/patterns/#_labels – Chad

+10

Właściwie to jest złe, (a: User: Admin) to zapytanie opisuje, kiedy węzeł to "Użytkownik a także administrator" Brak użytkownika LUB administratora. –

Powiązane problemy