将 WITH / CASE 子句链接在一起

Chaining WITH / CASE clauses together

我正在尝试为节点设置标签以适当地描述它们,因为它们是通过 LOAD CSV 语句创建的(请参阅我在此过程中遇到的先前问题:)。我已经能够在创建阶段设置一个标签,但现在我想应用多个标签中的一个,每个标签都有自己的一组条件,并且每个标签都是互斥的。

所以,如果我的 CSV 文件中包含以下内容:

"username","id","latitude","longitude","placeLatitude","placeLongitude"
"abc123","111111111","33.223","33.223"
"abc456","222222222","","","33.223","33.223"

我希望将用户 abc123 标记为 "geo",将用户 abc456 标记为 "placegeo"。这似乎是 Neo4j/Cypher 应该能够轻松完成的事情,但似乎存在局限性,因为我希望所有决策都在一个声明中完成。

我一直在尝试以下代码:

LOAD CSV WITH HEADERS FROM "file:d:/Users.csv" AS line
CREATE (p:Person { username: line.username, id: line.id, statusLat: line.statusLat, statusLon: line.statusLon, placeLat: line.placeLat, placeLon: line.placeLon })
WITH p, CASE WHEN (line.statusLat <> "" AND line.statusLat <> "0.0") THEN [1] ELSE [] END AS geotagged
FOREACH (a IN geotagged | SET p:Geo)
WITH p, CASE WHEN (COUNT(LABELS(p)) = 1 AND line.placeLat <> "" AND line.placeLat <> "0.0") THEN [1] ELSE [] END as place
FOREACH (b IN place | SET p:placegeo);

我也试过:

LOAD CSV WITH HEADERS FROM "file:d:/Users.csv" AS line
CREATE (p:Person { username: line.username, id: line.id, statusLat: line.statusLat, statusLon: line.statusLon, placeLat: line.placeLat, placeLon: line.placeLon })
WITH p, CASE WHEN (line.statusLat <> "" AND line.statusLat <> "0.0") THEN [1] ELSE [] END AS geotagged
FOREACH (a IN geotagged | SET p:Geo)
WITH p, COUNT(LABELS(p)) AS lb WHERE lb = 1,
CASE WHEN (line.placeLat <> "" AND line.placeLat <> "0.0") THEN [1] ELSE [] END as place
FOREACH (b IN place | SET p:placegeo);

(以及其他变体)似乎我无法将 WITH/CASE 语句链接在一起。

本质上,我想评估第一组条件,如果满足,添加标签,停止并移至 CSV 文件中的下一行。否则继续下一组条件并重复。如果我可以在 SET 中发出 "STOP" 或 "EXIT" 命令,那很好。

由于互斥性(即,如果它是一个标签,则不是另一个),我无法嵌套 FOREACH。

有办法吗?

你们非常接近。这应该适合你:

LOAD CSV WITH HEADERS FROM "file:d:/Users.csv" AS line
CREATE (p:Person { username: line.username, id: line.id, statusLat: line.statusLat, statusLon: line.statusLon, placeLat: line.placeLat, placeLon: line.placeLon })
WITH p,
    CASE WHEN (line.statusLat <> "" AND line.statusLat <> "0.0") THEN [1] ELSE [] END AS geotagged,
    CASE WHEN ((line.statusLat = "" OR line.statusLat = "0.0") AND line.placeLat <> "" AND line.placeLat <> "0.0") THEN [1] ELSE [] END as place
FOREACH (a IN geotagged | SET p:Geo)
FOREACH (b IN place | SET p:placegeo);