创建上述图形的查询:
merge (:node{name : '1'});
merge (:node{name : '2'});
merge (:node{name : '3'});
merge (:node{name : '4'});
merge (:node{name : '5'});
merge (:node{name : '6'});
merge (:node{name : '7'});
merge (:node{name : '8'});
match (n1:node{name : '1'}), (n2:node{name : '2'}) merge (n1) -[:edge{cost : 100, Property1:'P1', Property2: 'P2'}]-> (n2)
match (n1:node{name : '2'}), (n2:node{name : '3'}) merge (n1) -[:edge{cost : 100, Property1:'P1', Property2: 'P2'}]-> (n2)
match (n1:node{name : '3'}), (n2:node{name : '4'}) merge (n1) -[:edge{cost : 200, Property1:'P1', Property2: 'P2'}]-> (n2)
match (n1:node{name : '1'}), (n2:node{name : '5'}) merge (n1) -[:edge{cost : 40, Property1:'P1'}]-> (n2)
match (n1:node{name : '5'}), (n2:node{name : '6'}) merge (n1) -[:edge{cost : 50, Property1:'P1'}]-> (n2)
match (n1:node{name : '6'}), (n2:node{name : '4'}) merge (n1) -[:edge{cost : 60, Property1:'P1'}]-> (n2)
match (n1:node{name : '1'}), (n2:node{name : '7'}) merge (n1) -[:edge{cost : 60, Property2: 'P2'}]-> (n2)
match (n1:node{name : '7'}), (n2:node{name : '8'}) merge (n1) -[:edge{cost : 60, Property2: 'P2'}]-> (n2)
match (n1:node{name : '6'}), (n2:node{name : '8'}) merge (n1) -[:edge{cost : 20, Property1:'P1'}]-> (n2)
match (n1:node{name : '8'}), (n2:node{name : '4'}) merge (n1) -[:edge{cost : 20, Property2: 'P2'}]-> (n2)
我想要以下查询的答案。
1到4之间的最短路径,其中关系属性:Property1 ='P1',关系属性:Property2 ='P2'(成本:400,1-> 2-> 3-> 4)
1至4之间的最短路径,其中关系属性:Property1 ='P1'(成本:150,1-> 5-> 6-> 4)。此处的路径(1-> 2-> 3-> 4)也是有效的,但是由于成本高昂,因此不是答案。
1至4之间的最短路径,其中关系属性:Property2 ='P2'(成本:140,1-> 7-> 8-> 4)。同样,这里的路径(1-> 2-> 3-> 4)也是有效的,但是由于代价高昂,所以这不是答案。
1到4之间的最短路径,其中关系属性:Property1 ='P1'或关系属性:Property2 ='P2'(成本:130,1-> 5-> 6-> 8-> 4)。在这里,任何路径都是有效的,但是上述路径是最佳路径。
1至4之间的最短路径,其中关系属性:Property1!='P1'。 (费用:140,1-> 7-> 8-> 4)。
这里,Property1可以是任何东西,Property2也可以是任何东西(分别不一定是'P1'和'P2'。)。在所有情况下,如果存在一条边的关系属性Property1 ='P3',则应考虑该边以获得最佳路径。
假设我也要根据节点条件(例如具有Property ='P5'的节点)以及关系条件进行过滤,可以这样做吗?
我使用密码查询语言。
在互联网上的良好搜索仅对非加权图(Cypher: Shortest Path with Constraint)给出了约束
尝试图算法库。 https://neo4j.com/docs/graph-algorithms/current/labs-algorithms/shortest-path/
//1.
MATCH (start:node {name: '1'}), (end:node {name: '4'})
CALL algo.shortestPath.stream(start, end, 'cost', {
nodeQuery:'MATCH (n:node) RETURN id(n) as id',
relationshipQuery:'MATCH (n:node)-[r:edge]->(m:node) WHERE r.Property1="P1" and r.Property2="P2" RETURN id(n) AS source, id(m) AS target, r.cost AS weight',
graph: 'cypher', duplicateRelationships: 'min'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).name AS name, cost;
//2.
MATCH (start:node {name: '1'}), (end:node {name: '4'})
CALL algo.shortestPath.stream(start, end, 'cost', {
nodeQuery:'MATCH (n:node) RETURN id(n) as id',
relationshipQuery:'MATCH (n:node)-[r:edge]->(m:node) WHERE r.Property1="P1" RETURN id(n) AS source, id(m) AS target, r.cost AS weight',
graph: 'cypher', duplicateRelationships: 'min'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).name AS name, cost;
//3.
MATCH (start:node {name: '1'}), (end:node {name: '4'})
CALL algo.shortestPath.stream(start, end, 'cost', {
nodeQuery:'MATCH (n:node) RETURN id(n) as id',
relationshipQuery:'MATCH (n:node)-[r:edge]->(m:node) WHERE r.Property2="P2" RETURN id(n) AS source, id(m) AS target, r.cost AS weight',
graph: 'cypher', duplicateRelationships: 'min'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).name AS name, cost;
//4.
MATCH (start:node {name: '1'}), (end:node {name: '4'})
CALL algo.shortestPath.stream(start, end, 'cost', {
nodeQuery:'MATCH (n:node) RETURN id(n) as id',
relationshipQuery:'MATCH (n:node)-[r:edge]->(m:node) WHERE r.Property1="P1" or r.Property2 = "P2" RETURN id(n) AS source, id(m) AS target, r.cost AS weight',
graph: 'cypher', duplicateRelationships: 'min'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).name AS name, cost;
//5.
MATCH (start:node {name: '1'}), (end:node {name: '4'})
CALL algo.shortestPath.stream(start, end, 'cost', {
nodeQuery:'MATCH (n:node) RETURN id(n) as id',
relationshipQuery:'MATCH (n:node)-[r:edge]->(m:node) WHERE coalesce(r.Property1, "P2")<>"P1" RETURN id(n) AS source, id(m) AS target, r.cost AS weight',
graph: 'cypher', duplicateRelationships: 'min'})
YIELD nodeId, cost
RETURN algo.asNode(nodeId).name AS name, cost;