neo4j 密码中加权最短路径的关系约束

Relationship Constraints on weighted shortest path in neo4j cypher

我正在试验 neo4j。 我有这样的图表。

创建上图的查询:

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. 1 到 4 之间的最短路径,其中关系 属性:属性1 = 'P1' 和关系 属性:属性2 = 'P2'(成本:400,1 -> 2 -> 3 -> 4)

  2. 1 到 4 之间的最短路径,其中关系 属性:属性1 = 'P1'(成本:150、1 -> 5 -> 6 -> 4).这里路径 (1 -> 2 -> 3 -> 4) 也是有效的,但由于它的成本很大,所以它不是答案。

  3. 1 到 4 之间的最短路径,其中关系 属性:属性2 = 'P2'(成本:140、1 -> 7 -> 8 -> 4).同样,这里的路径 (1 -> 2 -> 3 -> 4) 也是有效的,但由于它的成本很大,所以它不是答案。

  4. 1 到 4 之间的最短路径,其中关系 属性:属性1 = 'P1' 或关系 属性:属性2 = 'P2'(成本:130、1 -> 5 -> 6 -> 8 -> 4)。这里任何路径都是有效的,但上面的路径是最优的。

  5. 1 到 4 之间的最短路径,其中关系 属性:属性1 != 'P1'。 (成本:140,1 -> 7 -> 8 -> 4)。

这里,属性1可以是任何东西,属性2也可以是任何东西(不一定分别是'P1'和'P2')。在所有情况下,如果存在关系 属性 属性1 = 'P3' 的边,则应考虑该边的最佳路径。

假设我也想根据节点条件(如具有 属性 = '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;