我的任务是计算距城市的道路总长度。我正在使用OSM数据。将其导入数据库后,我具有以下结构(对我来说这似乎是逻辑,但是如果您认为有更好的方法,我可以更改):
我对Neo4J很陌生。我只有SQL数据库方面的经验,但是基于此,我觉得即使我的方法行得通,也会失去查询语言的优势(指速度)。
这就是我到目前为止所拥有的,但是还差得远。它多次输出相同的数字(错误的数字),而不是一个总数。我很确定我没有完全理解 with ,但不知道解决方案是什么:
CREATE (t:Tmp {total:0})
with t
MATCH (e:Entity {type:'road'})
with collect(e) as es, t
unwind es as entity
match p = ()-[r:connected {entity_id:entity.int_id}]->()
with entity, p,t
SET entity.lng = 0
with entity, p, t
unwind nodes(p) as nd
with t,nd,point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as point1, entity
SET entity.lng = entity.lng + distance(entity.p, point1)
with t,nd,point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as point1, entity
SET entity.p = point1
with entity, t
SET t.total = t.total + entity.lng
return t.total
答案 0 :(得分:0)
您的查询返回的是每个节点的当前t.total
结果,而不是总的总价值。而且似乎错误地计算了段中第一个节点的距离(第一个节点的距离应为0)。这也是非常低效的。例如,不必费心利用defines
关系。在neo4j查询中,至关重要的是要利用关系的力量来避免扫描大量不相关的数据。
此外,没有提及特定的“城市”。您的查询针对所有Entity
节点。如果您的数据库仅包含一个城市的Entity
个节点,那就可以了。否则,您将需要修改查询以仅匹配特定城市的Entity
个节点。
下面的查询可以使用defines
关系来有效地匹配{{1}(根据我从您的问题中收集的信息,并假设您的数据库仅具有单个城市的数据)每个start
段的}}节点,并使用该Entity
节点有效地找到感兴趣的start
节点:
connected
aggregating function MATCH (entity:Entity {type:'road'})-[:defines]->(start)
MATCH p=(start)-[:connected* {entity_id:entity.id}]->(end)
WHERE NOT EXISTS((end)-[:connected {entity_id:entity.id}]->())
SET entity.lng = 0
SET entity.p = point({longitude:toFloat(start.lon), latitude: toFloat(start.lat)})
WITH entity, p
UNWIND TAIL(NODES(p)) AS nd
WITH point({longitude:toFloat(nd.lon), latitude: toFloat(nd.lat)}) as pt, entity
SET entity.lng = entity.lng + distance(entity.p, pt)
SET entity.p = pt
RETURN SUM(entity.lng) AS total
用于返回所有实体的总SUM()
。不需要lng
节点。 t
子句仅匹配组成完整段的路径。该查询还将WHERE
初始化为entity.p
节点的point
,并将start
节点之后的UNWINDS
节点初始化。
如果有许多start
个节点,其值不是{road},而是Entity
,那么您可能还想在type
上创建一个index。