NEO4J 中的 FOREACH 语法

问题描述 投票:0回答:2

使用 FOREACH 语法时出错。

CASE WHEN i.IOType STARTS WITH 'D' THEN [1] ELSE [] END AS isDigital,
    CASE WHEN i.IOType STARTS WITH 'A' THEN [1] ELSE [] END AS isAnalog 
       FOREACH(_ IN isAnalog | 
        MERGE(aa:AnalogAlarm {tag: signalTag })
        WHERE i.signalTag CONTAINS aa.tag
        MERGE (i)-[:IS_ALARM]->(aa))
        FOREACH(_ IN isDigital | 
        MERGE(dig:DigitalAlarm {tag: signalTag })
        WHERE i.signalTag CONTAINS dig.tag
        MERGE (i)-[:IS_ALARM]->(dig))

所以我无法在 FOREACH 中使用 WHERE 子句。合适的语法是什么?

foreach neo4j
2个回答
0
投票

您没有显示

signalTag
来自哪里,因此我将在查询开始时使用
WITH
子句复制它。

我猜测您想要的是对于属性

signalTag
等于
signalTag
值的每个现有节点,您想要创建一个具有属性
tag
=
signalTag
的新节点。如果现有节点的
IOType
'A'
开头,则新节点将获得标签
AnalogAlarm
,或者如果它以
'D'
开头,则将获得
DigitalAlarm
标签。然后,新节点通过
IS_ALARM
关系连接到现有节点。

如果这是真的,您可以通过几个

CALL
子查询来实现:

WITH 'ABC' AS signalTag
CALL {
    WITH signalTag
    MATCH (i WHERE i.signalTag = signalTag AND i.IOType STARTS WITH 'A')
    MERGE (aa:AnalogAlarm {tag: signalTag})
    MERGE (i)-[:IS_ALARM]->(aa)
}
CALL {
    WITH signalTag
    MATCH (j WHERE j.signalTag = signalTag AND j.IOType STARTS WITH 'D')
    MERGE (dig:DigitalAlarm {tag: signalTag})
    MERGE (j)-[:IS_ALARM]->(dig)
}

CALL
子查询是必要的,以便所包含的
MATCH
子句的基数不会相互影响。


0
投票

您的查询有很多语法错误,并且对于

FOREACH
子句来说有点太复杂(并且不太容易理解),特别是因为有更好的替代方法。

注意:我的答案假设

signalTag
实际上应该是
i.signalTag
,在这种情况下,不需要您的
WHERE
测试。

使用 CALL 子查询的片段

...

CALL {
  WITH i
  WITH i WHERE i.IOType STARTS WITH 'A'
  MERGE (a:AnalogAlarm {tag: i.signalTag})
  MERGE (i)-[:IS_ALARM]->(a)
}
CALL {
  WITH i
  WITH i WHERE i.IOType STARTS WITH 'D'
  MERGE (a:DigitalAlarm {tag: i.signalTag})
  MERGE (i)-[:IS_ALARM]->(a)
}

...

使用 apoc.do.case

的片段
...

CALL apoc.do.case([
  i.IOType STARTS WITH 'A',
    'MERGE(a:AnalogAlarm {tag: i.signalTag}) MERGE (i)-[:IS_ALARM]->(a)',
  i.IOType STARTS WITH 'D',
    'MERGE(a:DigitalAlarm {tag: i.signalTag}) MERGE (i)-[:IS_ALARM]->(a)'
  ],
  NULL,
  {i: i}
) YIELD value

...
© www.soinside.com 2019 - 2024. All rights reserved.