遍历具有Neo4j中的标签列表的图表

unftdfkk  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(169)

我有这个图表:

CREATE (a:Class {brickClass: 'Building',id:"building1"})
CREATE (b:Class {brickClass: 'Air Handler Unit', id:"ahu1"})
CREATE (c:Class {brickClass: 'Cooling System', id:"cools1"})
CREATE (d:Class {brickClass: 'Heat Exchanger', id:"heatex1"})
CREATE (e:Class {brickClass: 'Heat Exchanger', id:"heatex2"})
CREATE (f:Class {brickClass: 'Heat Exchanger', id:"heatex3"})
CREATE (g:Class {brickClass: 'Pump', id:"pump1"})
CREATE (h:Class {brickClass: 'Pump', id:"pump2"})
CREATE (i:Class {brickClass: 'Pump', id:"pump3"})
CREATE (a)-[r:has_equipment]->(b)
CREATE (a)-[s:has_equipment]->(c)
CREATE (b)-[t:has_equipment]->(d)
CREATE (b)-[u:has_equipment]->(e)
CREATE (c)-[w:has_equipment]->(f)
CREATE (d)-[v:has_equipment]->(g)
CREATE (e)-[x:has_equipment]->(h)
CREATE (f)-[y:has_equipment]->(i)

我想返回位于热交换器下方的所有泵,该热交换器也位于建筑物下方的空气处理装置下方。因此,输入为以下路径:

["Building","Air Handler Unit","Heat Exchanger","Pump"]

我试着对此进行编码,结果是以下代码:

WITH ["Building","Air Handler Unit","Heat Exchanger","Pump"] AS labels
UNWIND range(0, size(labels)-1) AS i
WITH labels[i] AS label1, labels[i+1] AS label2, i, labels
match (n:Class{brickClass:label1})-[*..]->(node2:Class{brickClass:label2})
WHERE i + 1 = size(labels) - 1
RETURN node2.id

这段代码没有返回我想要的。这段代码返回所有的泵。但是我希望它只返回泵1和泵2。我该如何更改代码来实现这一点呢?标签列表可能有不同的长度和标签,所以我不能做任何硬编码。

9q78igpj

9q78igpj1#

在Neo4j中没有这样的内置功能。但是,只要有一点想象力,使用APOC就可以实现您的结果。
我们要做的是,我们将生成Cypher查询的外观,如果您可以手动编写它,那么根据您的示例以及参数中的4项,查询将如下所示:

MATCH path=(:`Class` {brickClass: "Building"})-[:has_equipment]->(:`Class` {brickClass: "Air Handler Unit"})-[:has_equipment]->(:`Class` {brickClass: "Heat Exchanger"})-[:has_equipment]->(:`Class` {brickClass: "Pump"}) RETURN path

为了基于输入元素生成查询,我们将在APOC中使用一些字符串函数,主要是apoc.text.join

WITH ["Building","Air Handler Unit","Heat Exchanger","Pump"] AS parts

// convert any item in list above into (:Class {brickClass: <value>})

WITH [x IN parts | apoc.text.format('(:`Class` {brickClass: "%s"})', [x])] AS parts

// start the query with `MATCH path=`, 
// add the query parts from above joined by the relationship type 
// and end with `RETURN path`

WITH 'MATCH path=' + apoc.text.join(parts, '-[:has_equipment]->') + ' RETURN path' AS query

RETURN query

这将返回以下查询字符串

MATCH path=(:`Class` {brickClass: "Building"})-[:has_equipment]->(:`Class` {brickClass: "Air Handler Unit"})-[:has_equipment]->(:`Class` {brickClass: "Heat Exchanger"})-[:has_equipment]->(:`Class` {brickClass: "Pump"}) RETURN path

现在我们可以使用另一个APOC函数apoc.cypher.run,它允许我们执行生成的查询,并返回一个名为.. value的值

WITH ["Building","Air Handler Unit","Heat Exchanger","Pump"] AS parts
WITH [x IN parts | apoc.text.format('(:`Class` {brickClass: "%s"})', [x])] AS parts
WITH 'MATCH path=' + apoc.text.join(parts, '-[:has_equipment]->') + ' RETURN path' AS query
CALL apoc.cypher.run(query, {})
YIELD value
RETURN value

结果如你所愿

现在,让我们对仅包含2个元素的示例进行相同的尝试

WITH ["Heat Exchanger", "Pump"] AS parts
WITH [x IN parts | apoc.text.format('(:`Class` {brickClass: "%s"})', [x])] AS parts
WITH 'MATCH path=' + apoc.text.join(parts, '-[:has_equipment]->') + ' RETURN path' AS query
CALL apoc.cypher.run(query, {})
YIELD value
RETURN value

结果也在那里,非常动态

相关问题