Używam odprężenia, aby utworzyć wiele węzłów w Neo4j. Problem polega na tym, że jeden z węzła jest duplikatem, zostanie odrzucony, a całe zapytanie nie powiedzie się. Chcę być w stanie stworzyć wiele relacji między tymi samymi węzłami, jeśli już istnieją ....G Przyjaciel może otrzymać wiele zaproszeń z tej samej osoby. Mam więc tablicę obiektów [{e-mail: xxx@mail.com}, {e-mail: yyy@mymail.com}, ...] do zaproszenia i e-maila sponsora sponsoramail. Ograniczenie wiadomości e-mail, więc próby utworzenia duplikatu nie powiedzie się i odrzuci całe zapytanie. Poniższe działa dobrze, gdy nie ma duplikatu.

MATCH (s {email: 'sponsor@gmail.com'})
UNWIND $arrayOfObjects as invitees
CREATE (i:Invitee) MERGE (s)-[r:INVITED {since: timestamp()}]->(i)
SET i=invitees

Próbowałem zastępować scalanie tworzenia tworzenia myślenia, że scalanie znajdzie dopasowanie i przystąpić do tworzenia relacji, ale nie działa .. nadal zduplikuj błąd. Krótko czyszczenia arrayofobjects przed wykonaniem zapytania jest kolejny sposób na to zrobić? Chcę, aby duplikować nie zawieść, ale stworzyć relację z istniejącym węzłem Invitee.

0
MichaelE 4 czerwiec 2018, 03:19

3 odpowiedzi

Najlepsza odpowiedź

Musisz scalić: Węzeł Invitee wraz z e-mailem Invitee. Jak już teraz tworzysz puste: węzły Invitee i dopiero po utworzeniu ustawiania adresu e-mail. Musisz scalić je z adres e-mail. (Również powinieneś użyć etykiety na pierwszym meczu, w przeciwnym razie robi allnodesscan ... Zakładam, że to: Invitee na razie, ale proszę wymienić dowolną etykietę).

MATCH (s:Invitee {email: 'sponsor@gmail.com'})
UNWIND $arrayOfObjects as invitee
MERGE (i:Invitee {email:invitee.email}) 
CREATE (s)-[r:INVITED {since: timestamp()}]->(i)
1
InverseFalcon 4 czerwiec 2018, 22:55

[EDYTOWANO]

Twój MERGE może pasować do dowolny istniejący Invitee, a Twój zestaw mógł spróbować zmienić wartość email do nieubezpiecznej wartości. Prawdopodobnie dlatego otrzymujesz naruszenie ograniczeń.

Jeśli chcesz tylko relacji INVITED (z najnowszym znacznikiem czasu) dla każdego invitee, to zapytanie może zrobić to, co chcesz:

MATCH (s {email: 'sponsor@gmail.com'})
UNWIND $arrayOfObjects as invitee
MERGE (i:Invitee {email: invitee.email})
ON CREATE SET i = invitee
MERGE (s)-[r:INVITED]->(i)
ON CREATE SET r.since = timestamp()

Ta zapytanie zakłada, że każda mapa w arrayOfObjects zawiera wyjątkową wartość właściwości email. (Należy również stworzyć indeks lub Ograniczenie wyjątkowości na {{x2 }} Aby przyspieszyć pierwszy MERGE.)

Klauzula MERGE (s)-[r:INVITED {since: timestamp()}]->(i) (która określa bieżącą znacznik czasu) jest wadliwy, ponieważ nie wykryłby istniejącego stosunku ze starszą wartością {x1}} - więc prawie zawsze stwarza nowy związek. Klauzula MERGE (s)-[r:INVITED]->(i) stworzyłaby tylko związek, jeśli nie istnieje.

Lub, jeśli chcesz śledzić znaczniki czasu każdego zaproszenia, można wykonać wartość since być tablicą znaczników znaczników, takich jak to:

MATCH (s {email: 'sponsor@gmail.com'})
UNWIND $arrayOfObjects as invitee
MERGE (i:Invitee {email: invitee.email})
ON CREATE SET i = invitee
MERGE (s)-[r:INVITED]->(i)
ON CREATE SET r.since = [timestamp()]
ON MATCH SET r.since = r.since + timestamp()
1
cybersam 4 czerwiec 2018, 19:44

Oba zgłoszony odpowiedź są dobrymi odpowiedziami. Składam tę odpowiedź z kilkoma niuansami dla tych, którzy przychodzą później. Głównym celem pytania miało być w stanie stworzyć wiele zaproszeń do znajomego, który jeszcze nie zaakceptował i będzie w stanie wizualizować te zaproszenia. Poniżej ustaliłem:

WITH ['tom@abc.com', 'tony@mymail.com',michael@gmail.com'] AS coll
UNWIND coll AS invitee
WITH DISTINCT invitee
MATCH (s:Sponsor {email: 'mary@gmail.com'})
MERGE (i:Invitee {email: invitee})
CREATE (s)-[r:INVITED {since: timestamp()}]->(i)
RETURN r;   

Pozwoliło mi to stworzyć wiele relacji dla każdego zaproszenia wysłanego do tej samej osoby, ale tylko w razie wysyłania w różnych czasach .... które mogę łatwo przeglądać.

0
MichaelE 5 czerwiec 2018, 11:59