Neo4j 使用条件属性创建/设置多个关系属性
我试图在加载CSV操作中设置多个关系属性,其中一个属性将始终设置,另一个属性仅在两个节点属于特定标签时设置。我似乎无法让它允许我将多个SET语句链接在一起,它们之间有一个条件 我正试图按照以下思路做一些事情:Neo4j 使用条件属性创建/设置多个关系属性,neo4j,cypher,Neo4j,Cypher,我试图在加载CSV操作中设置多个关系属性,其中一个属性将始终设置,另一个属性仅在两个节点属于特定标签时设置。我似乎无法让它允许我将多个SET语句链接在一起,它们之间有一个条件 我正试图按照以下思路做一些事情: LOAD CSV WITH HEADERS FROM "file:/smalltext.csv" AS line MATCH (a:Person { username: line.sender }) MATCH (b:Person { username: line.recipient })
LOAD CSV WITH HEADERS FROM "file:/smalltext.csv" AS line
MATCH (a:Person { username: line.sender })
MATCH (b:Person { username: line.recipient })
CREATE UNIQUE (a)-[r:MSGD ]->(b)
SET r.Msg = coalesce(r.Msg, []) + [line.Msg]
WITH a,b,r, WHERE a:Geotagged AND b:Geotagged,
SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(a.statusLat - b.statusLat)) + cos(radians(a.statusLat)) * cos(radians(b.statusLat)) * haversin(radians(a.statusLat - b.statusLon)))));
仅供参考,距离公式直接来自Neo4j,因此我认为它不仅在数学上是正确的,而且在语法上也是正确的
当且仅当两个节点都标记为“地理标记”时,才应设置“距离”特性。原因是,(所有事物的)减法函数不知道如何从数字中减去null(反之亦然),如果用户没有“地理标记”,lat/lon值将为null
我尝试将Msg属性的创建放在CREATE语句中,但它不允许我从relationship属性中引用relationship属性
“地理标签”标签在导入数据时设置(也在加载CSV中),并且仅当每个用户都有地理位置信息时才设置
我还想知道是否应该将距离属性设置为单独的关系?我宁愿把它和信息放在一起,但我也愿意思考这个问题
谢谢
编辑1
如果用户在初始节点创建阶段没有地理标记,我可以将lat/lon设置为0,但是如果不是绝对必须的话,我宁愿不操纵数据
编辑2
在将所有非地理标记节点的LAT和LON设置为0并重新运行关系导入后,Cypher仍然告诉我它无法使用0进行减法(见下文):
QueryExecutionKerneleException:不知道如何
用'33.223'减去(a.statusLat,b.statusLat)'0'`
现在我只是感到困惑…我本以为这不会有问题,但这仍然不是一个好的解决方案,因为当计算地理标记和非地理标记用户之间的距离时,它会给出我无法处理的实际(和错误)结果
编辑3
下面的答案确实有效,但是上面出现异常的原因是因为我试图对字符串进行减法(duh),所以在减法时通过toFloat()运行它们就可以解决这个问题。我尝试运行toFloat()并将结果存储在数据库中,但是如果字段返回NULL,则会完全删除该字段,这不是我想要的行为
如果有人能在同一个加载CSV操作中运行这两个集合,我将非常感激知道如何运行,因为这对于我的实际数据集来说远不是理想的。我希望这不是一个愚蠢的建议,但是 …将查询拆分为多个部分不是更简单吗?毫无疑问,您不能使用多个Cypher语句以多种方式导入和处理同一个CSV文件。根据您的问题,我假设关系
(a)-[r:MSGD]->(b)
的创建和属性r.msg
的设置工作正常。当尝试有条件地设置r.distance
时会出现问题。因此,运行另一个LOAD CSV
操作,如下所示:
LOAD CSV WITH HEADERS FROM "file:/smalltext.csv" AS line
MATCH (a:Person:Geotagged { username: line.sender })-[r:MSGD]->(b:Person:Geotagged { username: line.recipient })
SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(a.statusLat - b.statusLat)) + cos(radians(a.statusLat)) * cos(radians(b.statusLat)) * haversin(radians(a.statusLat - b.statusLon)))));
这应该只匹配那些同时带有:Person
和:geotagated
标签的节点,这些标签由MSGD
关系链接,因此,只有当两个Person
节点都带有geotagated
标签时,才满足设置r.distance
属性的条件
完整的代码如下所示:
LOAD CSV WITH HEADERS FROM "file:/smalltext.csv" AS line
MATCH (a:Person { username: line.sender })
MATCH (b:Person { username: line.recipient })
CREATE UNIQUE (a)-[r:MSGD]->(b)
SET r.Msg = coalesce(r.Msg, []) + [line.Msg]
LOAD CSV WITH HEADERS FROM "file:/smalltext.csv" AS line
MATCH (a:Person:Geotagged { username: line.sender })-[r:MSGD]->(b:Person:Geotagged { username: line.recipient })
SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(a.statusLat - b.statusLat)) + cos(radians(a.statusLat)) * cos(radians(b.statusLat)) * haversin(radians(a.statusLat - b.statusLon)))));
希望这会有帮助。不,这不是一个愚蠢的建议……我甚至没有考虑过再次阅读该文件。这将使实际数据(300万个节点和数百万个关系)的处理变得更加困难,但是……我仍然认为有一种方法可以在一个语句中完成这一切,但这确实起到了作用。更多细节在我的作品中。