Man*_*iri 3 csv neo4j graph-databases cypher
我正在尝试在 Neo4J 中加载一些数据。我有一个Person
已经设置好的节点。现在,该节点需要有一个email
属性,该属性应该是数组(或集合)。基本上,该email
属性需要有多个值,例如 -
email: ["abc@xyz.com", "abc@foo.com"]
Run Code Online (Sandbox Code Playgroud)
我在这里遇到了类似的问题,但所有答案都表明在创建节点本身时设置多个属性值。就像这个答案中的这个查询一样-
CREATE (e:Employee { name:"Sam",languages: ["C", "C#"]})
RETURN e
Run Code Online (Sandbox Code Playgroud)
但我的问题是Person
节点已经创建,我现在需要设置email
它的属性。
这是我必须加载的数据的一小部分 -
Personid|email
933|Mahinda933@hotmail.com
933|Mahinda933@yahoo.com
933|Mahinda933@zoho.com
1129|Carmen1129@gmail.com
1129|Carmen1129@gmx.com
1129|Carmen1129@yahoo.com
4194|Ho.Chi4194@gmail.com
4194|Ho.Chi4194@gmx.com
Run Code Online (Sandbox Code Playgroud)
此外,数据来自包含数千行的 CSV 文件,因此我的查询需要是通用的,我无法为每个单独的Person
节点设置属性。
当我用这个子集测试电子邮件属性的创建时,我的第一次尝试是这样的 -
MATCH (n:TESTPERSON{id:933})
SET n.email = "Mahinda933@hotmail.com"
RETURN n
MATCH (n:TESTPERSON{id:933})
SET n.email = "Mahinda933@yahoo.com"
RETURN n
Run Code Online (Sandbox Code Playgroud)
正如我所想,这只是将email
属性覆盖为最近查询中的值。
在查看了此处和 Cypher 文档上的答案后,我发现 Neo4J 允许您将数组/集合(同一类型的多个值)设置为属性值,然后我尝试了这个 -
// CREATE test node
CREATE (n:TESTPERSON{id:933})
RETURN n
// at this time, this node does not have any `email` property, so setup
// email as an array with one string value
MATCH (n:TESTPERSON{id:933})
SET n.email = ["Mahinda933@hotmail.com"]
RETURN n
// Now, using +=, I can append to the array of strings
MATCH (n:TESTPERSON{id:933})
SET n.email = n.email + "Mahinda933@yahoo.com"
RETURN n
// add a third value to array
MATCH (n:TESTPERSON{id:933})
SET n.email = n.email + "Mahinda933@zoho.com"
RETURN n
Run Code Online (Sandbox Code Playgroud)
如您所见,该email
属性现在具有多个值。
但问题是,由于我的 CSV 文件有数千行,我需要一个通用查询来执行此操作。
我想按照这里的CASE
文档使用一个声明,并尝试了这个 -
MATCH (n:TESTPERSON {id:933})
CASE
WHEN n.email IS NULL THEN SET n.email = [ "Mahinda933@hotmail.com"]
ELSE SET n.email = n.email + "Mahinda933@yahoo.com"
RETURN n
Run Code Online (Sandbox Code Playgroud)
但这只会引发错误 - mismatched input CASE expecting ;
。
我希望我可以使用这个查询作为我的 CSV 文件的通用方式,如下所示 -
LOAD CSV WITH HEADERS FROM 'FILEURL' AS line FIELDTERMINATOR `|`
MATCH (n:TESTPERSON {id:toInt(line.Personid)})
CASE
WHEN n.email IS NULL THEN SET n.email = [line.email]
ELSE SET n.email = n.email + line.email
Run Code Online (Sandbox Code Playgroud)
但我什至不知道这是否有效,即使CASE
错误已修复。
我真的很困惑,非常感谢任何帮助。谢谢。
如果您尝试获取的值为 null,则可以使用 COALESCE() 使用默认值。你可以这样使用它:
...
SET n.email = COALESCE(n.email, []) + "Mahinda933@yahoo.com"
...
每当您将值数组设置为节点属性时,最好考虑是否可以将这些值建模为与原始节点有关系的单独节点。
在这种情况下,:Email 节点与 :TESTPERSON 节点具有某种关系,每封电子邮件有一个 :Email 节点,并且从 :TESTPERSON 到多个 :Email 存在多个关系。
这里的一个优点是,如果您想确保系统中只有一个:电子邮件,您将能够支持唯一性约束,并且如果您有索引或唯一约束,您将能够通过电子邮件快速查找人员,因为查询将使用索引来查找 :Email,并且从那里开始,只有与电子邮件所有者的一种关系遍历。
当节点上的集合中有值时,您无法对集合中的值使用索引查找,因此您当前的模型将无法通过电子邮件快速查找人员。
归档时间: |
|
查看次数: |
2801 次 |
最近记录: |