2015-04-03 66 views
1

我试图通过一个LOAD CSV语句创建标签给节点以正确表征它们(请参阅我在此过程中的一个早期问题:SET label based on data within LOAD CSV)。我可以在创建阶段设置标签,但现在我想应用多个标签中的一个,每个标签都有自己的一组条件,并且每个标签都互相排斥。将WITH/CASE子句链接在一起

所以,如果我在我的CSV文件如下:

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

我希望用户ABC123被标记为“地理”和用户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); 

(在其他的变化),似乎我不能链/ CASE语句组合在一起。

本质上,我想评估第一组条件,如果符合条件,请添加标签STOP并移至CSV文件中的下一行。否则,转到下一组条件并重复。如果在SET中可以发出“STOP”或“EXIT”命令,那很好。

因为互相排斥(即如果它是一个标签,它不是其他),我无法嵌套FOREACH。

有没有办法做到这一点?

回答

2

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

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); 
+0

它会退出CASE块,一旦它符合那些特定条件?我有两个节点,这两个条件都会评估为true(即statusLat和plateLat条件),但是我只希望它尝试第一个CASE块,如果它是真的,退出。这是如何工作的? – Brooks 2015-04-03 16:37:20

+0

查看我更新的答案。 – cybersam 2015-04-03 16:46:55

+0

当我看到您的第一个答案并回复后,我的感觉就是解决方案。这是唯一的方法吗?这意味着,我实现的每个标签都需要检查每个案例的独特条件条款才能实现此目的.....没有其他方法可以做到这一点? – Brooks 2015-04-03 16:50:31