cancel
Showing results forΒ
Did you mean:Β

Head's Up! Site migration is underway. Phase 2: migrate recent content

More efficient way without cartesian product?

Node

Hello Community,

This does a proper job of building a relationship between two airports where I then indicate the distance between the airports in both miles and kilometers. The query build a cartesian product - is there a more efficient slash elegant way of performing this? I have tested this with a small subset of airports (8 airports, 64 relationships), but fear this will not scale to 10's of thousand of airports.

`MATCH (a:Airport), (b:Airport)WHERE  a.iata_code <> b.iata_codeWITH  a, b,  point({latitude:a.latitude_deg, longitude:a.longitude_deg, height: a.elevation_ft / 3.281}) AS p_a,  point({latitude:b.latitude_deg, longitude:b.longitude_deg, height: b.elevation_ft / 3.281}) AS p_bMERGE   (a)-[:DISTANCE_BETWEEN {distance_miles: round(point.distance(p_a, p_b) / 1609, 1),                          distance_kilometers: round(point.distance(p_a, p_b) / 1000, 1)}]-(b) `

Thanks much all,

Douglas

1 ACCEPTED SOLUTION
Ninja

Hello @DouglasWiley π

Here is a query where it reduce the number of operations but you still have a Cartesian product:

``````MATCH (a:Airport)
MATCH (b:Airport)
WHERE id(a) > id(b)
WITH
a, b,
point({latitude:a.latitude_deg, longitude:a.longitude_deg, height: a.elevation_ft / 3.281}) AS p_a,
point({latitude:b.latitude_deg, longitude:b.longitude_deg, height: b.elevation_ft / 3.281}) AS p_b
MERGE (a)-[r:DISTANCE_BETWEEN]-(b)
SET r += {
distance_miles: round(point.distance(p_a, p_b) / 1609, 1),
distance_kilometers: round(point.distance(p_a, p_b) / 1000, 1)
}``````

Regards,
Cobra

3 REPLIES 3
Ninja

Hello @DouglasWiley π

Here is a query where it reduce the number of operations but you still have a Cartesian product:

``````MATCH (a:Airport)
MATCH (b:Airport)
WHERE id(a) > id(b)
WITH
a, b,
point({latitude:a.latitude_deg, longitude:a.longitude_deg, height: a.elevation_ft / 3.281}) AS p_a,
point({latitude:b.latitude_deg, longitude:b.longitude_deg, height: b.elevation_ft / 3.281}) AS p_b
MERGE (a)-[r:DISTANCE_BETWEEN]-(b)
SET r += {
distance_miles: round(point.distance(p_a, p_b) / 1609, 1),
distance_kilometers: round(point.distance(p_a, p_b) / 1000, 1)
}``````

Regards,
Cobra

Thanks so much @Cobra! This is excellent. What is the rational with "WHERE id(a) > id(b)"?

The Cartesian product is equivalent to a matrix multiplication so this clause allows you to do the calculation only in one direction. Instead of doing nΒ² operations, there are (n(n-1))/2 operations. I don't know if it's clear π

Nodes 2022

NODES 2022, Neo4j Online Education Summit

All the sessions of the conference are now available online

Neo4j Resources