2017-07-03 12 views
6

Mam wykres neo4j, który wygląda tak:Cypher: Znajdź dowolną ścieżkę między węzłami

Graph overview

węzły:

  1. Niebieskie węzły: rachunek
  2. Red węzły: PhoneNumber
  3. Zielone węzły: e-mail

konstrukcja Wykres:

  • (: PhoneNumber) - [: PART_OF] -> (: rachunek)
  • (: E) - [: PART_OF] -> (: rachunek)

problem usiłuję rozwiązać jest

Znajdź dowolną ścieżkę, która istnieje między Account1 i Account2.

To co próbowałem dotąd bez powodzenia:

  1. MATCH p = shortestPath ((A1: Account {accId: '1234'}) - [] - (A2: Account { accId: '5678'})) RETURN p;
  2. MATCH p = najkrótsza ścieżka ((a1: konto {accId: '1234'}) - [: PART_OF] - (a2: konto {accID: 5678 '})) POWRÓT p;
  3. MATCH p = najkrótsza ścieżka ((a1: konto {accId: '1234'}) - [*] - (a2: konto {accID: "5678 '})) POWRÓT p;
  4. MECZ p = (a1: Konto {accID: '1234'}) < - [: PART_OF * 1..100] - (n) - [: PART_OF] -> (a2: Konto {accID: '5678' }) POWRÓT p;
  5. Takie same zapytania jak powyżej bez wywołania funkcji najkrótszej ścieżki.

Patrząc na wykres widzę, że istnieje ścieżka między tymi dwoma węzłami, ale żadne z moich zapytań nie daje żadnego wyniku. Jestem pewien, że jest to bardzo proste zapytanie, ale będąc nowym dla Cyphera, mam trudności z ustaleniem właściwego rozwiązania. Każda pomoc jest doceniana.

Dzięki.

+0

Czy możesz podać więcej szczegółów na temat tego, co dzieje się po uruchomieniu tych zapytań? –

Odpowiedz

4

Wszystkie te pytania są zgodne z prawdą, ale wymagają pewnych ulepszeń, aby wykonać pracę. Jednak w dłuższej perspektywie, aby uzyskać lepszy system do łatwego wyszukiwania połączeń między kontami, prawdopodobnie będziesz chciał zmienić swój wykres.

Rozwiązanie teraz: Making Your Work Zapytanie

drodze pomiędzy dwoma dowolnymi (n:Account) węzłów w wykresie będzie wyglądać mniej więcej tak:

(a1:Account)<-[:PART_OF]-(:Email)-[:PART_OF]->(ai:Account)<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->(a2:Account)

Ponieważ masz tylko jedno typ relacji na wykresie, dwa węzły zostaną połączone przez nieokreśloną liczbę wzorców, takich jak:

<-[:PART_OF]-(:Email)-[:PART_OF]->

lub

<-[:PART_OF]-(:PhoneNumber)-[:PART_OF]->

Więc twoi dwa węzły zostaną połączone poprzez nieokreślonej liczby pośrednich (:Account), (:Email) lub (:PhoneNumber) węzłów wszystkich połączonych -[:PART_OF]- relacji kierunek przemian. Niestety według mojej wiedzy (i bardzo chciałbym, żeby mnie tu poprawiono), używając prostego szyfrowania, nie można wyszukiwać powtarzającego się wzoru na bieżącym wykresie. Będziesz więc musiał po prostu użyć wyszukiwania nieukierunkowanego, aby znaleźć relacje między węzłami połączone za pośrednictwem (a1:Account) i (a2:Account). Tak, na pierwszy rzut oka zapytanie będzie wyglądać następująco:

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*]-(a2:Account { accId: {a2_id} })) 
RETURN * 

(zauważyć tutaj Użyłem cypher parameters zamiast liczb całkowitych można umieścić w oryginalnej wiadomości)

To bardzo podobna do zapytanie # 3 , ale, jak powiedziałeś - to nie działa. Zgaduję, co się dzieje, że nie zwraca wyniku lub zwraca wyjątek z pamięci? Problem polega na tym, że ponieważ twój wykres ma ścieżki kołowe, a zapytanie to będzie pasowało do ścieżki o dowolnej długości, algorytm dopasowujący będzie dosłownie kręcić się w kółko, aż zabraknie mu pamięci. Więc chcesz ustawić limit, jak w pytaniu nr 4, ale bez wskazówek (dlatego to zapytanie nie działa).

Ustawmy więc limit. Twoja granica 100 relacji jest niewielka, zwłaszcza w przypadku wykresu cyklicznego (tj. Jednego z okręgami) i potencjalnie może się równać w zakresie 2 100 ścieżek.

Jako zasada (bardzo dowolna) każde zapytanie o potencjalnej nieukierunkowanej i nieoznaczonej ścieżce o długości większej niż 5 lub 6 może powodować problemy, chyba że bardzo ostrożnie podchodzi do projektowania wykresów. W twoim przykładzie wygląda na to, że te dwa węzły są połączone za pomocą ścieżki o długości 8. Wiemy również, że dla dowolnych dwóch węzłów dana minimalna długość ścieżki będzie wynosić dwie (tj. Dwie relacje -[:PART_OF]-, jedna do drugiej i jedna z nich. węzeł oznaczony jako :Email lub :PhoneNumber) i że dowolne dwa konta, jeśli są połączone, będą połączone za pomocą parzystej liczby relacji.

Najlepiej byłoby, gdybyśmy określili długość relacji między 2 a 10. Jednak funkcja cypher'a shortestPath() obsługuje tylko ścieżki o minimalnej długości 0 lub 1, więc ustawiłem ją w zakresie od 1 do 10 w przykład poniżej (choć wiemy, że w rzeczywistości najkrótsza ścieżka ma długość co najmniej dwóch).

MATCH p=shortestPath((a1:Account { accId: {a1_id} })-[:PART_OF*1..10]-(a2:Account { accId: {a2_id} })) 
RETURN * 

Mam nadzieję, że to będzie działać z Twoim przypadku użycia, ale należy pamiętać, że nadal może być bardzo intensywny pamięci do uruchomienia na dużą wykresu.

Longer Rozwiązanie Termin: Refactor Graph i/lub Użyj Ap

zależności od przypadku użycia, lepsze lub dłużej rozwiązanie termin byłby byłaby swój wykres, aby być bardziej szczegółowe na temat relacji przyspieszyć razy zapytania gdy chcesz znaleźć konta połączone tylko przez e-mail lub numer telefonu - np. -[:ACCOUNT_HAS_EMAIL]- i -[:ACCOUNT_HAS_PHONE]-. Możesz także użyć narzędzia APOC shortest path algorithms lub path finder functions, które najprawdopodobniej zwróci szybszy wynik niż przy użyciu szyfrowania, i pozwoli ci bardziej szczegółowo określić typy relacji w miarę rozwijania wykresu, aby uzyskać więcej danych.

+1

Dzięki Dom, działało to jak urok. Rozumiem teraz podstawową wadę mojego projektu wykresu. Poprawię projekt i wypróbuję APOC. Nigdy wcześniej ich nie próbowałem. Dzięki jeszcze raz. – Agandalf

Powiązane problemy