【发布时间】:2019-04-30 11:04:02
【问题描述】:
有没有办法编写一个 Cypher 查询,该查询返回从给定节点到其叶子节点的所有现有路径中所有(选定)关系属性总和最高的路径?
你好, 首先我要说明我是如何创建图表的:
CREATE CONSTRAINT ON (j:JOB) ASSERT j.order_id IS UNIQUE
USING PERIODIC COMMIT 1000
//EXPLAIN
LOAD CSV WITH HEADERS FROM "file:///jobs.csv" AS row
MERGE (j:JOB {order_id: row.child_order_id})
SET j.job_name = row.child_job_name,
j.job_owner = row.child_job_owner,
j.group_name = row.child_group_name,
j.order_time = row.child_order_time,
j.start_time = row.child_start_time,
j.end_time = row.child_end_time;
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///child_father.csv" AS row
MATCH (c:JOB {order_id: row.child_order_id})
MATCH (f:JOB {order_id: row.father_order_id})
MERGE (c)-[d:DEPENDS_ON]->(f)
SET d.elapsed_min = row.elapsed_min;
现在,我的目标是将给定订单 ID 中关系属性“elapsed_min”总和最大的路径返回到它所依赖的所有叶节点。
由于我在 Cypher 中找不到这样做的方法,因此我尝试使用 py2neo 库在 python 上进行操作。 起初我尝试使用普通的 Dijksta 算法来返回最轻的路径,在我能做到之后我会改变算法以返回最重的路径
所以我做了这个:
import py2neo
from py2neo import Graph
from py2neo import Node, Relationship
NEO4J_URI = "bolt://127.0.0.1:7687"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "neo4j"
graph = Graph(NEO4J_URI, auth = (NEO4J_USER, NEO4J_PASSWORD), bolt = True)
def dijkstra(graph,start,goal):
shortest_distance = {}
predecessor = {}
unseenNodes = graph
infinity = 999999
path = []
for node in unseenNodes:
shortest_distance[node] = infinity
shortest_distance[start] = 0
while unseenNodes:
minNode = None
for node in unseenNodes:
if minNode is None:
minNode = node
elif shortest_distance[node] < shortest_distance[minNode]:
minNode = node
for childNode, weight in graph[minNode].items():
if weight + shortest_distance[minNode] < shortest_distance[childNode]:
shortest_distance[childNode] = weight + shortest_distance[minNode]
predecessor[childNode] = minNode
unseenNodes.pop(minNode)
# get the path
currentNode = goal
while currentNode != start:
try:
path.insert(0,currentNode)
currentNode = predecessor[currentNode]
except KeyError:
print("Path not reachable")
break
if shortest_distance[goal] != infinity:
print('Shortest distance is: ' + str(shortest_distance[goal]))
print('And the path is: ' + str(path))
现在我需要找到一种方法以这种 json 格式返回路径,这样我就可以在其上运行 Dijkstra 算法,如下所示:
testGraph = {'a':{'b':10,'c':3},'b':{'c':1,'d':2},'c':{'b':4,'d':8,'e':2},'d':{'e':7},'e':{'d':9}}
#the relation property that means the distance from node: a to b is 10, a to c is 3, b to c is 1 and so on...
dijkstra(testGraph, 'a', 'd')
#the output is: Shortest distance is: 9
# And the path is: ['c', 'b', 'd']
但我不确定如何返回正确的路径以及哪种格式最适合.. 这就是我所拥有的,我无法将其发送到我的算法:
testGraph = graph.run( "MATCH (c:JOB)-[d:DEPENDS_ON*]->(f:JOB) "
"WHERE c.order_id = '4p0ta' "
"RETURN * "
"LIMIT 50").to_table()#data() #to_subgraph #to_data_frame()
【问题讨论】:
标签: python neo4j cypher dijkstra py2neo