在查询中,我提供以下参数:
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'}
如果有人能提供帮助,我会非常感激,因为我完全坚持这个:/
答案 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])然后它返回一个带有一个值的数组 - 值数组中的值使用与键数组中匹配的索引相同的索引