【问题标题】:Neo4j Merge doesn't use unique constraint indexNeo4j Merge 不使用唯一约束索引
【发布时间】:2015-08-19 10:27:21
【问题描述】:

Neo4j 版本 2.2.4

我使用 LOAD CSV 来导入大量节点和关系。我使用 MERGE 来获取或创建节点。为了提高性能,我还为节点属性创建了一个唯一索引。

CREATE CONSTRAINT ON (e:RESSOURCE) assert e.url is unique;

USING PERIODIC COMMIT 10000
LOAD CSV FROM 'file:///Users/x/data.csv' AS line FIELDTERMINATOR '\t'
MERGE (subject:RESSOURCE {url: trim(line[0])})
MERGE (object:RESSOURCE {url: trim(line[1])})
CREATE (subject)-[:EQUIVALENCE]->(object);

问题是导入了大约1Mio。边缘表现非常糟糕。我分析了导入和单个 MERGE 查询,但我看不到唯一索引的任何用法。相反, MATCH 查询使用索引。怎样才能将 MERGE 与索引一起使用?

【问题讨论】:

    标签: neo4j


    【解决方案1】:

    彼得是正确的,需要更多解释:

    您遇到了 EAGER 问题,请参阅:http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/ 您应该在 EXPLAIN 输出中看到它(删除定期提交并使用说明)

    +--------------+----------------------------------+-----------------------+
    | Operator     | Identifiers                      | Other                 |
    +--------------+----------------------------------+-----------------------+
    | +EmptyResult |                                  |                       |
    | |            +----------------------------------+-----------------------+
    | +UpdateGraph | anon[179], line, object, subject | CreateRelationship    |
    | |            +----------------------------------+-----------------------+
    | +UpdateGraph | line, object, subject            | MergeNode; :RESSOURCE |
    | |            +----------------------------------+-----------------------+
    | +Eager       | line, subject                    |                       |
    | |            +----------------------------------+-----------------------+
    | +UpdateGraph | line, subject                    | MergeNode; :RESSOURCE |
    | |            +----------------------------------+-----------------------+
    | +LoadCSV     | line                             |                       |
    +--------------+----------------------------------+-----------------------+
    

    Eager 将拉入您的整个 CSV 文件以确保隔离并有效地禁用您的定期提交。

    如果你做两遍,你也可以试试:

    CREATE CONSTRAINT ON (e:RESSOURCE) assert e.url is unique;
    
    USING PERIODIC COMMIT 10000
    LOAD CSV FROM 'file:///Users/x/data.csv' AS line FIELDTERMINATOR '\t'
    FOREACH (url in line[0..1] |
       MERGE (subject:RESSOURCE {url: trim(url)})
    );
    
    USING PERIODIC COMMIT 10000
    LOAD CSV FROM 'file:///Users/x/data.csv' AS line FIELDTERMINATOR '\t'
    MATCH (subject:RESSOURCE {url: trim(line[0])})
    MATCH (object:RESSOURCE {url: trim(line[1])})
    CREATE (subject)-[:EQUIVALENCE]->(object);
    

    【讨论】:

    • 是的,这就是我们在导入过程中所做的 - 我们首先将所有节点引入一个或多个 CSV(每个节点 100000 个节点),然后使用上述 MATCH MATCH MERGE 命令引入关系。
    【解决方案2】:

    试试这个:

    MATCH (subject:RESSOURCE {url: trim(line[0])}), (object:RESSOURCE {url: trim(line[1])}) 
    MERGE (subject)-[:EQUIVALENCE]->(object)
    

    编辑: 我看到你也想合并节点 - 我建议为每个节点做一个 MERGE:

    MERGE (subject:RESSOURCE {url: trim(line[0])})
    

    我还建议您在构建 csv 文件时进行修剪,以便限制 neo4j 执行此操作的次数并简化此密码。

    编辑 2(感谢 Kai 的评论纠正了我的上述 MERGE 声明):

    如果您想使用更多属性进行更复杂的 MERGE,您可以这样做:

    MERGE (subject:RESSOURCE {url: trim(line[0])})
      ON CREATE SET source=trim(line[1])
      ON MERGE SET source=trim(line[1])
    

    【讨论】:

    • MERGE (subject:RESSOURCE {url: trim(line[0])}) 和 MERGE (subject:RESSOURCE {url: trim(line[0])}) ON CREATE 有区别吗SET subject.url=trim(line[0]) 我认为在它不存在的情况下合并已经创建了节点
    • 是的,你是对的,我的错。仅当您想设置其他属性时,才需要 ON CREATE SET(和相关的 ON MATCH SET)子句。
    猜你喜欢
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 2011-03-18
    • 2021-11-02
    • 2011-11-23
    • 2018-12-02
    相关资源
    最近更新 更多