首页 > 解决方案 > Neo4J Cypher - 执行特定的 MATCH 语句并根据初始 MATCH 语句的结果返回结果

问题描述

我希望能够返回MATCH语句的结果,如果没有找到该语句的结果,我希望查询然后尝试不同的MATCH语句。我试图用一个CASE声明来做到这一点,但我一直遇到错误,特别是目前:

java.util.concurrent.CompletionException: org.neo4j.driver.v1.exceptions.ClientException: Invalid input ')': expected whitespace or a relationship pattern

MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})-[:INHERITS]-()-[:INCLUDES]-(p: itemProperty)
                                                  ^

完整查询:

MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})[:INCLUDES]-(p: itemProperty)
WITH ic, i, p, //only ever going to match on one (p: itemProperty) node
CASE WHEN COUNT(p) < 1 // when p node isn't found
THEN //try find a p node elsewhere
  MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})-[:INHERITS]-(i2: item)-[:INCLUDES]-(p: itemProperty)
END 
WITH p
OPTIONAL MATCH (p)-[r]-(pr:private)
WITH p, r, pr
RETURN p, COLLECT(DISTINCT r) AS rs, COLLECT(DISTINCT pr) AS prs

我什至不确定这是否是使用该CASE语句的适当和正确的方式。但是,这是我到目前为止所到之处,我什至不确定错误是什么。我可以匹配 case 语句中的路径吗?还是问题是其他原因造成的?

非常感谢对我当前问题的任何帮助,或任何其他可能也有效的建议。

编辑:我还注意到,如果我在 WITH 语句之后有一个逗号,WITH ic, i, p,那么它将达到我上面描述的错误,但是如果我删除最后一个逗号,它会在WHEN COUNT(p) < 1. 为什么会这样?我以前没有遇到过这种行为。

编辑2:我正在尝试以稍微不同(更简单)的方式做同样的事情。

MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})[:INCLUDES]-(p: itemProperty)
WITH ic, i, p, COUNT(p) as p_count
MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})-[:INHERITS]-(i2: item)-[:INCLUDES]-(p2: itemProperty)
WITH p_count, p2
CASE WHEN p_count < 1 
THEN result = p2
ELSE result = p
END 
WITH result
OPTIONAL MATCH (result)-[r]-(pr:private)
WITH result, r, pr
RETURN result, COLLECT(DISTINCT r) AS rs, COLLECT(DISTINCT pr) AS prs

但是,我收到以下错误:

java.util.concurrent.CompletionException: org.neo4j.driver.v1.exceptions.ClientException: Invalid input 'S': expected 'l/L' (line 6, column 4 (offset: 855))
"  WHEN p_count < 1"
 ^

我不明白这'S'是从哪里来的。

标签: neo4jcypherconditional-statementsmatch

解决方案


在第一个查询中,Invalid input ')': expected whitespace or a relationship pattern是因为您在[:INCLUDES]第一行缺少 - before也不支持 CASE 内部的(i: item {id: "???"})[:INCLUDES]-(p: itemProperty) 使用。MATCH

在第二个示例中,-之前缺少相同的内容,[:INCLUDES]并且resultCASE 中的 必须使用不同的别名。这个应该工作

MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})-[:INCLUDES]-(p: itemProperty)
WITH ic, i, p, COUNT(p) as p_count
MATCH (ic: itemContainer {id: "???", version: 1})-[:CONTAINS]->(i: item {id: "???"})-[:INHERITS]-(i2: item)-[:INCLUDES]-(p2: itemProperty)
WITH p_count, p2,
CASE WHEN p_count < 1 
THEN  p2
ELSE p
END AS result
WITH result
OPTIONAL MATCH (result)-[r]-(pr:private)
WITH result, r, pr
RETURN result, COLLECT(DISTINCT r) AS rs, COLLECT(DISTINCT pr) AS prs

推荐阅读