【问题标题】:Neo4j cypher LOAD command with wrong where conditionNeo4j 密码加载命令错误的 where 条件
【发布时间】:2016-12-11 02:38:15
【问题描述】:

我有两张表事件和地点。

我已将它们下载到 csv 文件中。

我运行以下查询来创建节点:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:////path/tb_location.csv" AS row
CREATE(:tb_location{ latitude: row.latitude,longitude: row.longitude,location_description: 
row.location_description,community_area: row.community_area,block: row.block,district: row.district,ward: row.ward,x_coordinate: row.x_coordinate,y_coordinate: row.y_coordinate,id_city: row.id_city,composite_key: row.composite_key });


USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:////path/tb_incident.csv" AS row
CREATE(:tb_incident{ id: row.id,primary_type: row.primary_type,domestic: row.domestic,date: row.date,description: row.description,arrest: row.arrest,beat: row.beat,year: row.year,updated_on: row.updated_on,latitude : row.latitude,longitude: row.longitude,case_number: row.case_number,composite_foreign_key: row.composite_foreign_key});

然后我在匹配属性上创建索引:

CREATE INDEX ON :tb_incident(composite_foreign_key);

CREATE INDEX ON :tb_location(composite_key);

然后我尝试建立关系:

USING PERIODIC COMMIT 10000
LOAD CSV WITH HEADERS FROM "file:////path/tb_incident.csv" AS row1
MATCH(tb_incident:tb_incident{composite_foreign_key: row1.composite_foreign_key})
LOAD CSV WITH HEADERS FROM "file:////path/tb_location.csv" AS row2
MATCH(tb_location:tb_location{composite_key: row2.composite_key})
WHERE tb_incident.composite_foreign_key = tb_location.composite_key
MERGE (tb_incident)-[:occured_at]->(tb_location);

但是,最后一个查询将一个事件链接到所有位置。 我是 cypher 的新手,我找不到我做错了什么。我打算仅将一个事件与一个位置联系起来。 如果您能帮我纠正这个不正确的查询,请提供帮助。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    由于您已经导入了所有数据,因此无需再使用您的 CSV 文件。这可能是导致您的问题的原因。

    试试这个:

    MATCH (tb_incident:tb_incident), (tb_location:tb_location)
    WHERE tb_incident.composite_foreign_key = tb_location.composite_key
    MERGE (tb_incident)-[:occured_at]->(tb_location);
    

    该查询的复杂度为 N*M(其中 N 是 tb_incident 节点的数量,M 是 tb_location 节点的数量),因此可能需要一段时间。不幸的是,neo4j 在比较节点之间的值时不使用索引。

    [更新]

    通过在导入期间创建关系来提高性能

    当您从第二个 CSV 文件导入时,您不仅可以创建每个 tb_incident 节点,还可以创建对应关系。它使用的MATCH应该能够使用索引,因为它不需要比较节点之间的值。这意味着这一步的复杂度降低到只有 N:

    USING PERIODIC COMMIT 10000
    LOAD CSV WITH HEADERS FROM "file:////path/tb_incident.csv" AS row
    CREATE(tb_incident:tb_incident{ id: row.id,primary_type: row.primary_type,domestic: row.domestic,date: row.date,description: row.description,arrest: row.arrest,beat: row.beat,year: row.year,updated_on: row.updated_on,latitude : row.latitude,longitude: row.longitude,case_number: row.case_number,composite_foreign_key: row.composite_foreign_key})
    WITH tb_incident, row.composite_foreign_key AS cfk
    MATCH (tb_location:tb_location{composite_key: cfk})
    MERGE (tb_incident)-[:occured_at]->(tb_location);
    

    【讨论】:

    • 这又做了和我的查询一样的事情。将一个事件连接到所有位置。有趣的是最后一个事件(id 最高的事件是关系所依附的事件)
    • 我试图遵循this 指南。他们还使用索引。我错过了什么吗?
    • 嗯。你能看看你数据库中的几个位置节点(MATCH (location:tb_location) RETURN location LIMIT 5),看看它们是否有相同的composite_key?如果这样做的结果是连接到多个位置,那让我认为位置没有正确创建,有很多具有相同的复合键。
    • @cybersam 如果您首先在 tb_incident 上匹配,并且在位置上与连接键上的 WHERE 匹配事件,您能否将其降低到复杂度 N?使用复合键上的索引,应该消除笛卡尔连接,对吧?
    • 愚蠢的我,实际上你是对的....我试图先在一个 5 行的表上做它,而不是一个有百万行的表。看起来我没有正确提取位置复合键。它们在所有 5 行中都是相同的。我会解决这个问题,然后试一试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多