2016-05-29 3 views
0

(Verwendung Neo4j 3.x und die neo4j.v1 Python Treiber)Merging Knoten auf dem Weg eine (Verbindung) Berechnen von Eigenschaften der Beziehung

Ich habe eine Spur aus einer verknüpften Liste von Knoten, die jeweils eine Darstellung eines (lon, lat) Koordinatenpaar.

(A)-[:NEXT]->(B)-[:NEXT]->(C) etc. with properties lon, lat on each node

Frage 1

Der direkte Abstand zwischen den Koordinaten von zwei benachbarten Knoten, z.B. (0,0) und (1,1), könnte als "distance" -Eigenschaft der Beziehung - [: NEXT {distance: 1,41421}] -> zwischen den beiden benachbarten Knoten hinzugefügt werden. Wie konntest du das tun, da ich Tausende solcher Knoten habe?

From the coordinates of A and B, a distance can be calculated and added as a property to the relationship

Frage 2

Ganze Segmente dieser verknüpften Liste von Knoten, die durch eine einzige ersetzt werden könnte - [: NEXT] -> Beziehung mit dem „Abstand“ Eigenschaft als die Summe aller die Abstände zwischen benachbarten Knoten der ursprünglichen Liste. Wie könnte dies effizient für Tausende oder mehr Knoten getan werden?

(A)-[:NEXT {distance: 1}]->(B)-...->(D)-[:NEXT {distance: 1}]->(E) (A)-[:NEXT {distance: 4}}->(E)

The distance between individual nodes in the first graph is added and the result assigned to the distance property in graph two, with all the intermediate nodes removed

Vielen Dank für Ihre Unterstützung und Hinweise.

Antwort

1

Teil1: Sie verwenden Lat/Lon, in Neo4j 3.0 gibt es native Unterstützung für Punkt und Abstand, stellen Sie sicher, latitude und longitude Eigenschaft Schlüssel zu verwenden. Anschließend können Sie diese Eigenschaft auf die Beziehung mit dem folgenden:

MATCH (start:YourNodeLabel)-[r:NEXT]->(end) 
SET r.distance = distance(point(start), point(end))/1000 

Teil 2: Wenn Sie die Start- und Endknoten des Pfades kennen, können Sie dann diese nächste Beziehung erstellen, indem die Distanzeigenschaften der Beziehungen zu reduzieren : mit diesem

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"}) 
MATCH (start)-[r:NEXT*]->(end) 
CREATE (start)-[newrel:NEXT]->(end) 
SET newrel.distance = reduce(d=0.0, x IN r | d + x.distance) 

vorsichtig

jedoch, unter Berücksichtigung, dass es in diesem Fall für beispielsweise mehr als ein path von start zu end, sein könnte, wenn Sie den kürzesten Abstand vom Anfang bis zum Ende finden möchten, müssen Sie muss die Gesamtdistanz berechnen und die niedrigste nehmen e:

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"}) 
MATCH p=(start)-[:NEXT*]->(end) 
WITH p, start ,end, reduce(d=0.0, x IN rels(p) | d + x.distance) as totalDistance 
ORDER BY totalDistance ASC 
LIMIT 1 
CREATE (start)-[newRel:NEXT]->(end) 
SET newRel.distance = totalDistance 

Wenn Sie auf die Beziehungen der Abstand Eigenschaften nicht haben, können Sie auch die geo Entfernung im laufenden Betrieb in den reduzieren Funktionen berechnen:

MATCH (start:YourNodeLabel {name:"A"}), (end:YourNodeLabel {name:"E"}) 
MATCH p=(start)-[:NEXT*]->(end) 
WITH p, start, end, 
reduce(d=0.0, x IN range(1, size(nodes(p))-1) | d + distance(point(nodes(p)[x-1]), point(nodes(p)[x]))/1000) as distance 
ORDER BY distance ASC 
LIMIT 1 
CREATE (start)-[newRel:NEXT]->(end) 
SET newRel.distance = distance 

Als allgemeine Hinweise gegeben, ich würde nicht den gleichen Namen des Beziehungstyps für die Beziehung verwenden, die als Verknüpfung verwendet wird, vielleicht CONNECT_TO oder REACH_POINT kann besser geeignet sein, um die NEXT Beziehungen in anderen Abfragen nicht zu stören.

+0

Brilliant, das ist sehr hilfreich. Ich danke dir sehr! Side Question: Wenn ich einige seltsame Metriken und, sagen wir, Raum-Zeit-Koordinaten hätte, wie würden Sie Ihre Entfernungsberechnung implementieren? Als gespeicherte Prozedur? Ich bin froh, dass Neo4j 3.x native Unterstützung für Geodienste bietet, aber man weiß nie ... – user3650713

+0

Ja, wenn Sie ein bisschen Java machen können, würde ich mit Verfahren gehen –