2016-05-21 9 views
1

Ich mache ein "Freund eines Freundes" Typ MATCH in Neo4j. Das einzige, was mich abstößt, ist ein Versuch, alle Beziehungen nach Datum zu beschränken.Passen Sie FOAF an, aber beschränken Sie Pfad für Datum; speziell in einer sequentiellen Weise, in Neo4j

Die Grund Graph ist in etwa so:

enter image description here

Die 'echte' Version des Graphen hat 10 1.Grad Freunde und 3385 2. Grades Freunde.

Und obwohl ich keine Datum-Eigenschaft auf jeder Kante auf dem Bild oben gesetzt habe, ist das tatsächlich der Fall. Zu den Daten gibt es keine Reihenfolge.

Die allgemeine Idee ist ziemlich einfach: Ich möchte sicherstellen, dass jede Beziehung ignoriert wird, die eine Datumseigenschaft aufweist, die älter als ein vorbestimmtes maximales Datum ist.

Der etwas trickreiche Teil ist, dass, wenn die maximale Datumsbeschränkung innerhalb der ersten Beziehung verletzt wird (wie auf einer der drei Kanten, die vom Knoten im Bild oben kommen), diese Kante in zwei Hälften geteilt wird und keine andere Dieser Pfad sollte in der Lage sein, zu durchlaufen. (z.B. möchte ich keinen der Blattknoten).

Ich schrieb dies:

MATCH 
(n)-[f1:FRIEND]-()-[f2:FRIEND]-(m) 
WITH n, m,split('1962-1-1', '-') AS maxdate 
WHERE n.person_id='180' 
AND(
(
toInt(maxdate[0]) > toInt(split(f1.date, '-')[0]) 
) 
OR 
(
toInt(maxdate[0]) = toInt(split(f1.date, '-')[0]) 
AND 
toInt(maxdate[1]) >= toInt(split(f1.date, '-')[1]) 
)) 
AND(
(
toInt(maxdate[0]) > toInt(split(f2.date, '-')[0]) 
) 
OR 
(
toInt(maxdate[0]) = toInt(split(f2.date, '-')[0]) 
AND 
toInt(maxdate[1]) >= toInt(split(f2.date, '-')[1]) 
)) 
RETURN m; 

Dieser Codeblock für etwa 20 Minuten lief und erscheint schließlich in etwas in der Nähe geführt zu haben, was ich strebe. Hier ist, wie es im Browser aussieht:

enter image description here

(Es verfügt über 350 Knoten)

Erstens, ich gebe zu, dass dies eindeutig einig schrecklich geschriebenen Code (sowohl in Bezug auf Ästhetik und Leistung). Zweitens bemerke ich die nicht verbundenen Knoten im Umkreis.

Was passiert ist, ist, wenn der Date-Zustand der First-Degree-Beziehung fehlschlägt, aber die Second-Degree-Beziehung nicht, und so bin ich am Ende mit dem "Freund eines Freundes", den ich nicht will enthalten sein.

Wie kann ich meine Datumsbedingung so ändern, dass ich diese freistehenden Knoten eliminiere, wenn die Kante ersten Grades ungültig wird?

Wenn jemand irgendeine Einsicht hat, würde ich es sehr schätzen. (Nicht zu matschig werden, aber dank der SO-Community bin ich schon relativ schnell ziemlich weit gekommen, und dafür bin ich dankbar.)

Antwort

2

Es sollte nicht so lange an erster Stelle laufen, das Der Hauptgrund ist, dass Sie kein Label + Index auf Ihren Knoten haben.

addd die zuerst:

CREATE CONSTRAINT ON (p:Person) ASSERT p.person_id is unique; 
MATCH (n) where exists(n.person_id) SET n:Person; 

wenn Sie Ihre Zeit in yyyy-mm-dd sowieso (ich so zumindest hoffen) Sie sie direkt vergleichen: (mit 2 Stellen aka 01) d'2012-01-10' > '2011-08-31')

WITH '1962-01-01' AS maxdate 
MATCH (n:Person)-[f1:FRIEND]-()-[f2:FRIEND]-(m:Person) 
WHERE n.person_id='180' AND f1.date < maxdate and f2.date < maxdate 
RETURN m; 

Sie können auch die Kurzform verwenden: (n:Person {person_id:'180'})

, wenn Sie einen allgemeinen Ausdruck über die Beziehungen in einem Weg haben wollen, verwenden Sie eine Variable rels (die dann eine Sammlung ist) in Ihrem variabler Länge Pfad Muster:

WITH '1962-01-01' AS maxdate 
MATCH (n:Person {person_id:'180'})-[rels:FRIEND*2]-(m:Person) 
WHERE ALL(r in rels WHERE r.date < maxdate) 
RETURN m; 

Sie auch rels(path)

WITH '1962-01-01' AS maxdate 
MATCH path = (n:Person {person_id:'180'})-[:FRIEND*2]-(m:Person) 
WHERE ALL(r in rels(path) WHERE r.date < maxdate) 
RETURN m; 
012 verwenden können

oder wenn die Beziehungen eines Pfades in Beziehung zueinander stehen:

WITH '1962-01-01' AS maxdate 
MATCH (n:Person {person_id:'180'})-[rels:FRIEND*2]-(m:Person) 
WHERE ALL(idx in range(0, size(rels)-2) WHERE (rels[idx]).date < maxdate AND (rels[idx]).date < (rels[idx+1]).date) 
RETURN m; 
+0

Ich bin immer noch diese seltsamen, isoliert und getrennt Knoten auf dem Umfang bekommen ... Bedarf weiter zu untersuchen (und ich plötzlich erkennen es ist 4:45 Uhr!) –

+1

das passiert immer :) (die Zeit meine ich) Ich habe die Syntax in der letzten behoben (verpasste eine Klammer) –

+0

Gibt es ein Ranking dieser Abfragen in Bezug auf die Leistung? –