我使用py2neo通过CSV上传导入数据。以下脚本读取每个列及其文件行并推送到Neo4j。文件包含四列下的数千行。有些列包括" n / a"," undefined"," null"," unknown"和空白细胞。当脚本迭代列和行时,它会将所有数据也推送到数据库。
我希望,当脚本读取" n / a"或" undefined"," null" ...它应该忽略这些数据并且不会推送数据库。
result_data = "./Excel2CSV/result.csv"
graph.cypher.execute("CREATE CONSTRAINT ON (result:RESULT) ASSERT result.id IS UNIQUE")
with open(result_data, 'r+') as in_file:
reader = csv.reader(in_file, delimiter=';')
next(reader, None)
batch = graph.cypher.begin()
try:
i = 0;
j = 0;
for row in reader:
if row:
f_name = strip(row[0])
l_name = strip(row[1])
nickname = strip(row[2]
text = strip(row[3])
result = strip(row[4])
query = """
merge (person:Person {f_name:{a}, l_name{b}, nickname{c}})
merge (text:TEXT {value:{d}})
merge (Result:RESULT {value:{e}})
merge (person)-[:WROTE]->(text)
merge (person)-[:REPLIED]->(result)
"""
batch.append(query, {"a": f_name, "b": l_name, "c": nickname, "d": text, "e": result})
i += 1
j += 1
batch.process()
例如,我正在创建一个名为" person"此节点有3个属性" f_name"来自{a}列," l_name"来自{b}列和"昵称"来自{c}专栏。假设每列都具有上述"不需要的"值。我使用第一个" f_name"创建了节点。属性:
WITH CASE WHEN {a} IN ["n/a", "undefined", "null"] THEN "" ELSE {a} END AS x
OPTIONAL MATCH (person:Person { f_name: x })
并且在传递给
之前 WITH CASE WHEN text IS NULL THEN [x] ELSE [] END AS todo
FOREACH (i IN todo | CREATE (person:Person { l_name: i })),
我需要应用相同的过滤来删除" l_name"和#34;昵称"属性。而且我认为我应该定义新属性以将新属性附加到" person"节点
答案 0 :(得分:1)
您可以修复上一个查询,以使其“正常”。但是,该方法仍然存在缺陷,因为数据库最终可能会有多个:TEXT
节点没有属性。这是因为具有“bad”属性的每个MERGE
将无法匹配现有节点并使用该属性创建新的新节点,然后删除该属性(因为您将其值设置为null
) - 可能不是你想要的。
所以,我建议你选择一个非空值(例如,“”,甚至是字符串“null”)来设置值,如果传入的{c}
有一个“坏”值。
使用上述提议,如果节点只有一个属性,则以下简单查询应该有效(用“”替换“坏”值):
WITH CASE WHEN {c} IN ["n/a", "undefined", "null"] THEN "" ELSE {c} END AS x
MERGE (text:TEXT { value: x });
这不仅符合您的意图,而且效率更高,因为它不需要额外的WHERE
OR SET
条款。
由于MERGE
子句(指定任何属性)仅匹配完成属性集与子句匹配的节点,因此如果要查找的话,上述单属性解决方案将不起作用匹配即使节点具有MERGE
子句中未指定的其他属性。
如果应该允许“额外”属性,这是一个应该有效的查询。
WITH CASE WHEN {c} IN ["n/a", "undefined", "null"] THEN "" ELSE {c} END AS x
OPTIONAL MATCH (text:TEXT { value: x })
WITH CASE WHEN text IS NULL THEN [x] ELSE [] END AS todo
FOREACH (i IN todo | CREATE (text:TEXT { value: i }));
OPTIONAL MATCH
不像MERGE
那样挑剔,即使有“额外”属性也会成功。如果OPTIONAL MATCH
失败,则会将null
分配给其节点和关系标识符。如果它迭代的集合是空的,FOREACH
什么都不做。