我正在构建一个小型的转换应用程序。我想在这个过程中学习图形数据库。我做了一个模型,我有一个带有多个运行检查项目的changetracker。在运行A中我找到了1,2,3,4,5,在下一次运行中我可能会找到1,2,4,5,6。
所以我做了一个简单的模型
(:ChangeTracker)-[:Has_Run]->(:Run)
(:Run)-[:NEXT]->(:Run)
(:Run)-[:HAS_Found]->(:Item)
以下查询在基准测试时最终会非常慢(50.000项会导致查询时间> 10秒)
PROFILE
MATCH
(t:WebsiteTracker {Id : 'fde6fd1f-a899-5295-b73b-63fa75d131f4'})-[:HAS_SiteMapRun]->(lastRun)<-[:NEXT*0..2]-(run)
WHERE NOT (lastRun)-[:NEXT]->()
with t,run
MATCH
(run)-[:NEXT]->(runNext),
(runNext)-[:HAS_Found]->(itm)
WHERE
NOT(run)-[:HAS_Found]->(itm)
RETURN
t.Id, t.Name, run, itm
ORDER BY
runNext.Start
我想部分NOT(runPrev)-[:HAS_Found]->(itm)
是罪魁祸首,但我怎样才能让我的查询更好?
正如所料,部件NOT(runPrev)-[:HAS_Found]->(itm)
正在击中每个项目节点,但结果看起来还不错。
答案 0 :(得分:0)
如果你有APOC Procedures,你可以使用apoc.coll.pairsMin()获取每次运行的相邻对,并对项目集合使用apoc.coll.subtract()来查找新元素在上一次运行中没有出现。
这需要Neo4j 3.1,因为我们使用模式理解来获取每次运行的项目列表。
这样的事情:
MATCH
(t:ChangeTracker)-[:HAS_Run]->(run)
WHERE
t.Id = 'fde6fd1f-a899-5295-b73b-63fa75d131f4'
AND NOT (run)-[:NEXT]->()
MATCH
(runPrev)-[:NEXT*0..7]->(run)
WITH t, runPrev
ORDER BY runPrev.Start
WITH t, COLLECT({run:runPrev,
items:[(runPrev)-[:HAS_FOUND]->(itm) | itm]}) as runs
WITH t, apoc.coll.pairsMin(runs) as runPairs
UNWIND runPairs as runPair
WITH HEAD(runPair) as runPrev, LAST(runPair) as runNext
WITH t, runPrev, runNext,
apoc.coll.subtract(runNext.items, runPrev.items) as newItems
RETURN t.Id, t.Name, runNext.run as run, newItems
ORDER BY
run.Start