Cypher Neo4j - 在集合中使用“IN”子句的查询非常慢

时间:2015-12-03 15:39:50

标签: neo4j cypher

您好我正在尝试从 Neo4j 2.3.1 中的CSV文件导入一些数据。我已经导入了一些类型的节点:作者:文章

作者节点由以下属性组成:

  1. key - >串
  2. principal_name - >串
  3. 别名 - >字符串集合
  4. ........
  5. 我还在principal_name,别名和密钥上添加了索引。

    当我尝试导入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做到这一点吗?

2 个答案:

答案 0 :(得分:1)

如果您更改了模型,以便所有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)上创建索引,则此查询应非常有效。

答案 1 :(得分:0)

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

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

在所有节点上添加索引。如果可能,请使用uniqueness constraints

您现在可以查询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)

使用索引,查找速度应该非常快。