collection/json Neo4j apoc 中每个节点的最短路径
Shortest path for each node in collection/json Neo4j apoc
简短任务描述:我有一个 json 文档,由一组 origin/source 个节点组成,对于每个节点,我需要找到第一个、第二个和第三个最短路径目标节点。输入json如下:
{
"origin":[
{"label":"Alcohol drinks",
"tag":[],
"type":"string",
"xpath":[]
},
{"label":"Wine",
"tag":["red","white"],
"type":"string",
"xpath":["Alcohol drinks"]
},
{"label":"Port wine",
"tag":["Portugal","sweet","strong"],
"type":"string",
"xpath":["Alcohol drinks","Wine"]
},
{"label":"Sandeman Cask 33",
"tag":["red","expensive"],
"type":"string",
"xpath":["Alcohol drinks","Wine","Port wine"]
}
],
"target":[
{"label":"Drinks",
"tag":[],
"type":"string",
"xpath":[]
},
{"label":"Tea",
"tag":["black", "green"],
"type":"string",
"xpath":["Drinks"]
},
{"label":"Carbonated water",
"tag":[],
"type":"string",
"xpath":["Drinks","Tea"]
},
{
"label":"Pepsi",
"tag":["sweet","cheap"],
"type":"string",
"xpath":["Drinks","Tea","Carbonated water"]
}
]
}
节点已经插入到DB中,并建立对应关系。节点是相连的,因此可以构建至少一条从起点到目标的路径。
为了找到最短路径,我使用以下 Cypher 查询:
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig UNWIND value.target AS tar
MATCH(origin:concept{name:orig.label})
MATCH(target:concept{name:tar.label}),
path = shortestPath((origin)-[*1..3]-(target)) RETURN path ORDER BY length(path) ASC LIMIT 4
此查询将所有源节点映射到所有目标节点。但我需要这样的东西:
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig UNWIND value.target AS tar
MATCH(origin:concept{name:orig.label}) MATCH(target:concept{name:tar.label})
FOREACH (x IN orig.label
| MERGE(origin:concept{name:orig.label})
MERGE(target:concept{name:tar.label})
path = shortestPath((origin)-[*1..3]-(target))) RETURN path ORDER BY length(path) ASC LIMIT 3
这个查询不起作用,但想法是能够使用 foreach 循环,获取第一个起点标签并尝试找到到其中一个目标的第 1、2、3 条最短路径,然后是第 2 个起点,第三个起源等。如果你能指出我,我将不胜感激,我如何使用 foreach 循环以正确的方式寻找短路径。提前致谢!
您不能以这种方式使用 FOREACH。
可能你最好的选择是使用 APOC 路径扩展程序,这些可以对最短路径使用 bfs 扩展,并且可以限制每次调用的结果数量(并且将为每个行配对执行一次调用起源和目标),所以通过正确的程序(在这里使用 spanningTree() 以确保我们只访问每个节点一次并且我们在最后 return 路径)你将获得每个 [= 的 3 条最短路径17=]组合.
这也有助于分别处理起点和目标,因为您当前的方法在它们之间创建了笛卡尔积,这似乎是您寻找路径所需的,但它会导致在寻找起点时浪费冗余匹配操作和目标节点。
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig
MATCH(origin:concept{name:orig.label})
WITH value, collect(origin) as origins
UNWIND value.target AS tar
MATCH(target:concept{name:tar.label})
UNWIND origins as origin
WITH origin, tar
CALL apoc.path.spanningTree(origin, {terminatorNodes:[tar], maxLevel:3, limit:3}) YIELD path
RETURN origin, tar, length(path) as pathLength, path
简短任务描述:我有一个 json 文档,由一组 origin/source 个节点组成,对于每个节点,我需要找到第一个、第二个和第三个最短路径目标节点。输入json如下:
{
"origin":[
{"label":"Alcohol drinks",
"tag":[],
"type":"string",
"xpath":[]
},
{"label":"Wine",
"tag":["red","white"],
"type":"string",
"xpath":["Alcohol drinks"]
},
{"label":"Port wine",
"tag":["Portugal","sweet","strong"],
"type":"string",
"xpath":["Alcohol drinks","Wine"]
},
{"label":"Sandeman Cask 33",
"tag":["red","expensive"],
"type":"string",
"xpath":["Alcohol drinks","Wine","Port wine"]
}
],
"target":[
{"label":"Drinks",
"tag":[],
"type":"string",
"xpath":[]
},
{"label":"Tea",
"tag":["black", "green"],
"type":"string",
"xpath":["Drinks"]
},
{"label":"Carbonated water",
"tag":[],
"type":"string",
"xpath":["Drinks","Tea"]
},
{
"label":"Pepsi",
"tag":["sweet","cheap"],
"type":"string",
"xpath":["Drinks","Tea","Carbonated water"]
}
]
}
节点已经插入到DB中,并建立对应关系。节点是相连的,因此可以构建至少一条从起点到目标的路径。
为了找到最短路径,我使用以下 Cypher 查询:
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig UNWIND value.target AS tar
MATCH(origin:concept{name:orig.label})
MATCH(target:concept{name:tar.label}),
path = shortestPath((origin)-[*1..3]-(target)) RETURN path ORDER BY length(path) ASC LIMIT 4
此查询将所有源节点映射到所有目标节点。但我需要这样的东西:
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig UNWIND value.target AS tar
MATCH(origin:concept{name:orig.label}) MATCH(target:concept{name:tar.label})
FOREACH (x IN orig.label
| MERGE(origin:concept{name:orig.label})
MERGE(target:concept{name:tar.label})
path = shortestPath((origin)-[*1..3]-(target))) RETURN path ORDER BY length(path) ASC LIMIT 3
这个查询不起作用,但想法是能够使用 foreach 循环,获取第一个起点标签并尝试找到到其中一个目标的第 1、2、3 条最短路径,然后是第 2 个起点,第三个起源等。如果你能指出我,我将不胜感激,我如何使用 foreach 循环以正确的方式寻找短路径。提前致谢!
您不能以这种方式使用 FOREACH。
可能你最好的选择是使用 APOC 路径扩展程序,这些可以对最短路径使用 bfs 扩展,并且可以限制每次调用的结果数量(并且将为每个行配对执行一次调用起源和目标),所以通过正确的程序(在这里使用 spanningTree() 以确保我们只访问每个节点一次并且我们在最后 return 路径)你将获得每个 [= 的 3 条最短路径17=]组合.
这也有助于分别处理起点和目标,因为您当前的方法在它们之间创建了笛卡尔积,这似乎是您寻找路径所需的,但它会导致在寻找起点时浪费冗余匹配操作和目标节点。
CALL apoc.load.json("file:///D:/project/neo_proj/input.json") YIELD value
UNWIND value.origin AS orig
MATCH(origin:concept{name:orig.label})
WITH value, collect(origin) as origins
UNWIND value.target AS tar
MATCH(target:concept{name:tar.label})
UNWIND origins as origin
WITH origin, tar
CALL apoc.path.spanningTree(origin, {terminatorNodes:[tar], maxLevel:3, limit:3}) YIELD path
RETURN origin, tar, length(path) as pathLength, path