2016-10-13 6 views
-1

Ich arbeite derzeit mit Isochronen auf Neo4j und PostGIS.Neo4j Isochrones Verbesserung

Mein Problem in Neo4j ist, dass meine Abfrage zur Berechnung von Isochronen nicht wirklich effizient ist.

match (n:node) where n.id_gis='155' 
with n 
match path=(n)-[*0..15]-(e) 
with e, min(reduce(cost=0.0, r IN rels(path) | cost + toFloat(r.cost2)*3600)) as cost 
where cost < 30 
return cost, collect(e) as isochrones 
order by cost 

Wie Sie im Code sehen können über i für maximalen Hops derzeit eine Grenze haben sonst, weil es für alle möglichen Pfade in der Datenbank suchen, bevor die maximal Kosten zu berechnen.

Hat jemand eine Idee, wie ich meine Abfrage ändern/verbessern kann, so dass es in einer "normalen" Zeit ausgeführt wird und ohne die Anzahl der Beziehungen zu begrenzen?

Antwort

1

Ich fürchte, Sie können nicht besser mit Cypher tun.

Sie können jedoch viel besser mit der traversal framework in Java. Sehen Sie diesen zweiteiligen Blogbeitrag, der die Cypher-Implementierung des Dijkstra-Algorithmus vergleicht (ähnliches Problem, nur mit festen Start- und Endknoten statt mit offenem Ende) mit APOC's: part 1 und part 2.

eine Traversal verwenden, können Sie die Kosten berechnen, während durchlaufen, die Sie ermöglicht:

  • den Zweig beschneiden, sobald die maximal Kosten
  • die besten Kosten sammeln erreicht sind bisher für ein Endknoten, und beschneidet den Zweig, wenn die Kosten für den Stromzweig ist schlimmer als die besten Kosten für die gleichen Endknoten

Sie ein Map<Node, Double> verwenden kann, die Kosten zu sammeln, obwohl, wenn IhrFormal Graph ist groß genug, die Verwendung einer primitiven Karte (wie fastutil, Trove, HPPC, Koloboke, etc.) wird viel weniger Speicher und in der Regel schneller (kompakter, weniger Boxen und Unboxing; Verwenden Sie einfach die long ID des Knotens als Schlüssel).

Sobald die Traversierung abgeschlossen ist, müssen Sie nur die Karte in eine Multimap von Kosten und zugehörigen Endknoten invertieren, um Ihr Ergebnis zu erhalten.

Es ist komplexer als das Ausführen einer Cypher-Abfrage, aber es wird viel, viel schneller.

+0

danke, das scheint wie eine gute Lösung. Wie kann ich eine Karte für jeden einzelnen Pfad speichern? – roman11

+0

Warum eine Karte für jeden Pfad? Die Karte stellt die Aggregation der beiden erreichbaren Knoten und Kosten dar und ist per Definition einzigartig. –

+0

Ich denke, ich habe es. Weißt du, ob es einen Weg gibt, um zu gehen, abhängig von der "Kosten" -Eigenschaft der Beziehungen (wie dijkstra) anstelle von depthFirst? Ich habe etwas über die Implementierung eines eigenen CostEvaluators und/oder PathExpanders gelesen, aber das scheint sehr kompliziert zu sein. – roman11