我有一个从 csv 导入的建筑风格时期数据库。每个
Style
都有一个 styId
,还有一个 infId
,显示了影响它的先前风格。
如果提到风格有影响,我想在风格之间建立关系,如下所示:
我知道这将是将
styId
与 infId
进行匹配,但我不是数据科学家,而且对 NEO4j 非常陌生。我可以通过手动指定关系来做到这一点,但我正在自己构建此数据集,并计划稍后添加更多条目,因此,如果有最佳实践通过单独使用 styId
和 infId
来创建这些关系,我更喜欢这个选项。
感谢您的帮助,如果有任何不清楚的地方请告诉我。
如果数据库中已有数据,则可以使用如下查询。创建关系后,它还会删除多余的
infId
属性。
MATCH (s1:Style)
WITH s1, SPLIT(s1.infId, ';') AS infs
MATCH (s2:Style)
WHERE s2.styId IN infs
CREATE (s1)-[:INFLUENCED_BY]->(s2)
REMOVE s1.infId // Remove redundant infId property
首先,你应该在styId
的
Style
属性上创建一个index,以加快查询速度:
CREATE INDEX Style_styId FOR (s:Style) ON (s.styId)
但是,更好的是,您应该在将数据提取到数据库时创建所需的数据模型,而不是事后修复数据库。
有多种方法可以将 CSV 导入 Neo4j。最简单的是通过 LOAD CSV,所以这里是一个例子。假设您的 CSV 文件有标题行:
CALL {
LOAD CSV WITH HEADERS FROM 'file:///styles.csv' AS r
CREATE (s:Style {id: r.styId, name: r.Style, dates: r.Dates, influences: SPLIT(r.Influences, ';')})
MERGE (loc:Location {name: r.Location})
CREATE (s)-[:LOCATION]->(l)
}
LOAD CSV WITH HEADERS FROM 'file:///styles.csv' AS row
MATCH (s1:Style)
WHERE s1.id = row.styId
WITH s1, SPLIT(s1.infId, ';') AS infs
MATCH (s2:Style)
WHERE s2.id IN infs
CREATE (s1)-[:INFLUENCED_BY]->(s2)
如果您有多个位置,您可能还想在
Location.name
上创建索引。
请注意,这会创建一个与您的数据模型略有不同的数据模型,因为:
每个
Style
节点都指向唯一的 Location
节点
influences
属性(您可能想省略)是一个字符串列表
styId
存储为 id
属性(因为很明显 id 是用于样式的)。这要求你的 id 索引是这样创建的:
CREATE INDEX Style_id FOR (s:Style) ON (s.id)
通过 CSV 文件中的 2 次导入完成摄取;第一个用于创建所有
Style
节点,第二个用于创建所有 INFLUENCED_BY
关系。 CALL 子查询 用于干净地分离 2 个 LOAD CSV
调用(否则,您需要在它们之间执行聚合,只是为了将行数减少到 1)。
上述解决方案假设您没有很多样式,因此它在单个事务中完成所有操作。如果您有很多样式,则必须更改(并且可能拆分)查询以避免内存不足和/或花费太长时间。