Chciałbym przeprowadzić wyszukiwanie i chciałbym rozpocząć przechodzenie od 2 etykiet (warunek LUB). Na przykład, muszę znaleźć wszystkie węzły, które mają etykiety "Male" lub "Female" i których własność, name = ~ '. ail. ".Neo4j: Dopasuj wiele etykiet (2 lub więcej)
Odpowiedz
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.
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)
Dlaczego potrzebujesz "różnych" na każdym kroku? –
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
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. –
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
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
FYI. Adres URL źródła nieco się zmienił. To jest nowe: https://neo4j.com/docs/developer-manual/current/cypher/syntax/patterns/#_labels – Chad
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. –
Czy jest to krótszy sposób? Dla np. dla relacji możesz podać '(n) - [: rel1 | rel2] -> (m) 'gdzie' | 'oznacza' OR' –
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
@Lyman Zerga również szukałem w wielu miejscach, ale nie mając nic takiego –