Cypher Neo4j - 在集合上使用子句'IN'的查询非常慢



嗨,我正在尝试从Neo4j 2.3.1中的CSV文件导入一些数据。我已经导入了一些类型为:Author:Article的节点。

Author节点由以下属性组成:

  1. ->字符串
  2. principal_name->String
  3. alias->字符串集合

我还添加了principal_name、alias和key的索引

当我尝试导入Article和Author类型的节点之间的关系时,问题就出现了。

CSV具有以下类型的结构:

articleKey,authorName

有一个天真的解决方案,我试图使用这样的查询来创建关系:

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///myPath.csv" AS line
MATCH (art:Article{key: line.key1})
MATCH (auth:Author) WHERE line.key2 IN (auth.alias)
CREATE UNIQUE (auth)-[:AUTHOR_OF]->(art);

查询非常慢,因为正如我使用探查器发现的那样,第二个MATCH非常慢。创建每个关系需要10-12秒,因为我在数据库中有很多作者(大约1000000)。

因此,我正在寻找一种方法来执行像这样的查询,以获得更快的执行(这是一个示例来说明我想要获得的结构):

MATCH (auth:Author{principal_name: line.key2})
IF auth null THEN
  MATCH (auth:Author) WHERE line.key2 IN (auth.alias)
END

Cypher有办法做到这一点吗?

如果您更改了模型,使Author节点的所有名称(主体名称和所有别名)都在单独的Name节点中,如下所示:

(auth:Author)-[:HAS_NAME]->(name:Name {name: 'Fred McGillicutty'})

那么查询将是简单的:

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///myPath.csv" AS line
MATCH
  (art:Article { key: line.key1 }),
  (auth:Author)-[:HAS_NAME]->(name:Name { name:line.key2 })
CREATE (auth)-[:AUTHOR_OF]->(art);

如果在:Article(key):Name(name)上创建索引,则此查询应该非常高效。

如果许多作者都有别名,并且您希望查询这些别名,则应将它们建模为节点。我认为这将加快创建关系的查询速度,并允许涉及别名的更灵活的查询。

(:Alias)<-[:HAS]-(:Author)-[:AUTHOR_OF]->(:Article)

在所有节点上添加索引。如果可能,使用唯一性约束。

现在可以查询AliasAuthor节点以添加关系:

USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:///myPath.csv" AS line
MATCH (art:Article {key: line.key1})
// get the Author directly or by alias
MATCH (alias:Alias)<-[:HAS]-(auth:Author)
WHERE alias.principal_name = line.key2 OR auth.principal_name = line.key2
CREATE (auth)-[:AUTHOR_OF]->(art)

有了索引,查找应该非常快。

最新更新