加载 csv 后链接查询的 Cypher 限制
Cypher restrictions on queries chained after a load csv
我目前正在使用 .net 中的螺栓驱动程序在我的图表中导入一些关系。对于这种情况,我想尝试 load csv
命令(源在 csv 中)并比较性能,但查询仅应用于第一行。我用 skip n limit 1
进行了测试,结果只能逐行做到 运行。
因此我想知道加载 csv 循环中的 "complex" 查询是否有任何限制?
这里是查询:
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
MATCH p=(o:Target {num:row[1]})-[:Version*..]->()
WHERE row[2] in labels(o)
WITH n, p ORDER BY LENGTH(p) DESC LIMIT 1
WITH n, last(nodes(p)) as m
MERGE (n)-[r:Rel]->(m);
谢谢!
编辑:
我的 csv 只是遵循此模式的常规 3 列 CSV:
IDTEXT0000000001;V150;LabelOne
IDTEXT0000000002;M245;LabelOne
IDTEXT0000000003;D666;Labeltwo
etc.
逐行我的意思是我首先在 with row
之后用 limit 50
进行了测试,因为它不起作用(没有添加任何内容)然后我做了 limit 1
,skip 1 limit 1
, `skip 2 limit 2, 等等。"row by row" 方法有效,但你会承认这不是你真正想做的。
最终代码:
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
MATCH p=(o:Target {num:row[1]})-[:Version*..]->()
WHERE row[2] in labels(o)
WITH n, p ORDER BY LENGTH(p) DESC
WITH n, last(nodes(collect(p)[0])) as m
MERGE (n)-[r:Rel]->(m);
使用 apoc(稍微快一点):
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
call apoc.cypher.run('MATCH p=(o:Article {num:$num})-[:VersionChristopher*0..]->() WHERE $label in labels(o) WITH p ORDER BY LENGTH(p) DESC LIMIT 1 return last(nodes(p)) as m', {num:row[1], label:row[2]})
yield value
with n, value.m as m
MERGE (n)-[r:Rel]->(m);
但是使用 bolt 可以让我在没有标签测试的情况下构建查询,并且仍然比加载 csv 快 3 到 4 倍。感谢您的帮助:)
问题在于您在查询中使用了 LIMIT:
WITH n, p ORDER BY LENGTH(p) DESC LIMIT 1
这不限制每行,LIMIT 适用于所有行。在每个 n(来自您的 CSV)和多个 p 路径有多行的情况下,应用此限制后,您只有一行,一个 n,一个 p,随后是一个 MERGE 操作。
你应该仔细阅读 how to limit results per row,一旦你确定你的查询应该没问题。
我目前正在使用 .net 中的螺栓驱动程序在我的图表中导入一些关系。对于这种情况,我想尝试 load csv
命令(源在 csv 中)并比较性能,但查询仅应用于第一行。我用 skip n limit 1
进行了测试,结果只能逐行做到 运行。
因此我想知道加载 csv 循环中的 "complex" 查询是否有任何限制?
这里是查询:
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
MATCH p=(o:Target {num:row[1]})-[:Version*..]->()
WHERE row[2] in labels(o)
WITH n, p ORDER BY LENGTH(p) DESC LIMIT 1
WITH n, last(nodes(p)) as m
MERGE (n)-[r:Rel]->(m);
谢谢!
编辑:
我的 csv 只是遵循此模式的常规 3 列 CSV:
IDTEXT0000000001;V150;LabelOne
IDTEXT0000000002;M245;LabelOne
IDTEXT0000000003;D666;Labeltwo
etc.
逐行我的意思是我首先在 with row
之后用 limit 50
进行了测试,因为它不起作用(没有添加任何内容)然后我做了 limit 1
,skip 1 limit 1
, `skip 2 limit 2, 等等。"row by row" 方法有效,但你会承认这不是你真正想做的。
最终代码:
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
MATCH p=(o:Target {num:row[1]})-[:Version*..]->()
WHERE row[2] in labels(o)
WITH n, p ORDER BY LENGTH(p) DESC
WITH n, last(nodes(collect(p)[0])) as m
MERGE (n)-[r:Rel]->(m);
使用 apoc(稍微快一点):
using periodic commit
LOAD CSV FROM "file:///path/to/my/file.csv" AS row fieldterminator ';'
with row
MATCH (n:Source {id:row[0]})
call apoc.cypher.run('MATCH p=(o:Article {num:$num})-[:VersionChristopher*0..]->() WHERE $label in labels(o) WITH p ORDER BY LENGTH(p) DESC LIMIT 1 return last(nodes(p)) as m', {num:row[1], label:row[2]})
yield value
with n, value.m as m
MERGE (n)-[r:Rel]->(m);
但是使用 bolt 可以让我在没有标签测试的情况下构建查询,并且仍然比加载 csv 快 3 到 4 倍。感谢您的帮助:)
问题在于您在查询中使用了 LIMIT:
WITH n, p ORDER BY LENGTH(p) DESC LIMIT 1
这不限制每行,LIMIT 适用于所有行。在每个 n(来自您的 CSV)和多个 p 路径有多行的情况下,应用此限制后,您只有一行,一个 n,一个 p,随后是一个 MERGE 操作。
你应该仔细阅读 how to limit results per row,一旦你确定你的查询应该没问题。