创建/设置来自Neo4j中的参数对象的属性

时间:2015-08-09 18:33:15

标签: java python neo4j

在查询中,我提供以下参数:

id : 'some unique ID',
used : [an array of md5 checksums]

使用以下查询:

MATCH (a {id:{id}}) , (b)
WHERE b.md5 IN {used}
CREATE UNIQUE (a)-[]->(b)

一切都很棒。如果used数组中有10个MD5校验和,则将从节点“a”向它们建立10个关系。凉。

但现在说我需要为该关系添加一个属性 - 该属性将取决于节点b。

所以现在我有一个额外的参数,一个对象,看起来像这样:

info : {
'5fb1be1279031c1f1c65a928eb823e51': 'yolo',
'0aab9f8e81684ec778f8c0c5717f37c2': 'swag',
...
}

此对象中的MD5键与used数组中的MD5字符串匹配。

我的第一直觉就是这样做:

MATCH (a {id:{id}}) , (b)
WHERE b.md5 IN {used}
CREATE UNIQUE (a)-[{ meme:{info}[b.md5] }]->(b)

因为那不起作用。我收到错误:

  

{[neo4j.ClientError:[Neo.ClientError.Statement.InvalidType]预期   e1701806eda7d3ab52b143cc03d94e75是一个java.lang.Number,但它是   一个java.lang.String]消息:   '[Neo.ClientError.Statement.InvalidType]预期   e1701806eda7d3ab52b143cc03d94e75是一个java.lang.Number,但它是   一个java.lang.String',neo4j:{code:   'Neo.ClientError.Statement.InvalidType',        消息:'期望e1701806eda7d3ab52b143cc03d94e75是一个java.lang.Number,但它是一个java.lang.String'},名称:   'neo4j.ClientError'}

如果有人能提供帮助,我会非常感激,因为我完全坚持这个:/

1 个答案:

答案 0 :(得分:1)

在仔细研究了Stefan的博客之后,我发现我可以使用以下Cypher来实现我的需求。 它并不漂亮,但除非有一种比FOREACH / CASE技巧更有条理地创建事物的方法,否则它必须这样做:

首先将键/值对的对象拆分为两个数组:

> fileMD5  : ['5fb1be1279031c1f1c65a928eb823e51','0aab9f8e81684ec778f8c0c5717f37c2'..]
> fileInfo : ['yolo','swag'...]

然后将表达式写成:

MATCH (e:event {id:{id}}),(r:resource)
WHERE r.md5 IN {used}
FOREACH(
  idx in RANGE(0,SIZE({fileMD5})-1) |
  FOREACH( 
    filePath IN CASE WHEN r.md5 = {fileMD5}[idx] THEN [{fileInfo}[idx]] ELSE [] END |
    CREATE UNIQUE (r)-[:USED_BY {filePath:filePath }]->(e)
  )
)

我在8个小时前写过这个问题,这意味着这几条小小的线条需要8个小时的时间才能完成。我希望其他人觉得它很有用:P

编辑:关于它如何/为何起作用的一些解释......

第一个FOREACH将RANGE从0迭代到(键或值数组-1的长度),其中idx变量是结果。这是同时迭代两个相同长度的数组的常用技巧。

第二个FOREACH有点复杂。它迭代一个由CASE创建的数组,结果称为filePath。但是CASE只返回一个没有任何内容的数组[],或者带有我们想要在CREATE中设置的值的数组。因此,根据案例,FOREACH要么做一次,要么什么都不做。

CASE非常简单。当索引拉出一个匹配我们想要的键时(r.md5 = {fileMD5} [idx])然后它返回一个带有一个值的数组 - 值数组中的值使用与键数组中匹配的索引相同的索引