【问题标题】:Cypher Neo4j - Query that uses the clause 'IN' on the collection is very slowCypher Neo4j - 在集合上使用子句“IN”的查询非常慢
【发布时间】:2015-12-03 15:39:50
【问题描述】:

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

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

  1. -> 字符串
  2. principal_name -> 字符串
  3. 别名 -> 字符串集合
  4. ........

我还在 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 做到这一点?

【问题讨论】:

    标签: neo4j cypher


    【解决方案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)上创建索引,这个查询应该非常高效。

    【讨论】:

    • 建议的解决方案与我之前认为的相同,以加快查询执行速度。当我对数据进行建模时,我天真地认为在集合上添加索引就可以解决问题。相反,我从分析器中看到集合上的索引不用于回答查询。
    【解决方案2】:

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

    (: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)
    

    使用索引查找应该很快。

    【讨论】:

    • 感谢您的回复,您提出的解决方案与@cybersam 提出的解决方案非常相似。我选择另一个只是因为更通用。最后是我不得不整理出来的相同想法。但我想知道为什么集合上的索引从未使用过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-30
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多