Neo4J - 如何做后期处理UNION(分页)

时间:2017-03-29 09:38:25

标签: neo4j cypher

我正在编写一个cypher查询来加载来自我的Neo4J数据库的数据,这是我的数据模型

data model

基本上我想要的是一个查询返回一个包含其所有属性及其相关内容的Journal,我尝试过做简单的查询,但它根本不具备性能,我托管数据库的ec2实例用完了记忆很快     MATCH p=(j:Journal)-[*0..]-(n) RETURN p

我设法使用UNIONS

编写查询
`MATCH p=(j:Journal)<-[:BELONGS_TO]-(at:ArticleType) RETURN p 
UNION 
MATCH p=(j:Journal)<-[:OWNS]-(jo:JournalOwner) RETURN p 
UNION
 
MATCH p=(j:Journal)<-[:BELONGS_TO]-(s:Section) RETURN p 
UNION 

MATCH p=(j:Journal)-[:ACCEPTS]->(fc:FileCategory) RETURN p 
UNION
MATCH p=(j:Journal)-[:CHARGED_BY]->(a:APC) RETURN p 
UNION
MATCH p=(j:Journal)-[:ACCEPTS]->(sft:SupportedFileType) RETURN p 
UNION
MATCH p=(j:Journal)<-[:BELONGS_TO|:CHILD_OF*..]-(c:Classification) RETURN p

SKIP 0 LIMIT 100`

查询工作正常,其性能一点也不差,我发现的唯一问题是极限,我一直在谷歌搜索,我已经看到了后处理查询目前尚不支持UNIONS。

引用的github问题尚未解决,因此无法对UNION进行后处理 github link

从逻辑上讲,当我遇到这个问题时,我尝试的第一件事就是对每个单独的查询进行分页,但这有一些奇怪的行为对我自己没有多大意义。

所以我尝试在不使用UNIONS的情况下编写查询,我想出了这个

`MATCH (j:Journal)
WITH j LIMIT 10
MATCH pa=(j)<-[:BELONGS_TO]-(a:ArticleType) 
MATCH po=(j)<-[:OWNS]-(o:JournalOwner)
MATCH ps=(j)<-[:BELONGS_TO]-(s:Section)
MATCH pf=(j)-[:ACCEPTS]->(f:FileCategory)
MATCH pc=(j)-[:CHARGED_BY]->(apc:APC)
MATCH pt=(j)-[:ACCEPTS]->(sft:SupportedFileType)
MATCH pl=(j)<-[:BELONGS_TO|:CHILD_OF*..]-(c:Classification)
RETURN pa, po, ps, pf, pc, pt, pl`

然而,这个查询打破了我的数据库,我觉得我错过了编写CQL查询所必需的东西...

我也在neo blog post中查看了COLLECT和UNWIND,但无法理解它。

如何在不删除联盟的情况下对查询进行分页?或者是否有任何其他方式来编写查询,以便可以在日记帐级别应用分页并且性能不受影响?

---编辑---

这是我的第二个查询的执行计划

enter image description here

1 个答案:

答案 0 :(得分:2)

你真的不需要UNION,因为当你使用UNION接近它时,你将获得每个:Journal节点的所有相关节点,并且只有你从每个节点获得所有这些扩展后:Journal节点你限制你的结果集。这是大量的工作,只会因你的LIMIT而被排除在外。

您的第二个查询看起来更正确的方法,匹配:具有LIMIT的日记节点,然后仅在相关节点上进行匹配以准备要返回的数据。

你说第二个查询破坏了你的数据库。您可以在查询(或EXPLAIN,如果查询永远不会执行)上运行PROFILE,展开计划的所有元素,并将其添加到您的描述中吗?

另外,如果您将最终的MATCH省略到:分类,查询是否正常运行?

了解您是否确实需要返回的路径,或者是否只返回已连接的节点也是有帮助的。

修改

如果您想要每个:日记及其所有连接数据在一行上,您需要在每次匹配后使用COLLECT(),或使用pattern comprehension,以便结果已经在集合中。

这也将减少不必要的查询。您的初始匹配(在限制之后)生成了31k行,因此所有后续匹配执行了31k次。如果你收集()或使用模式理解,你将基数保持在最初的10,并防止多余的匹配。

这样的话,如果你只想要收回路径:

MATCH (j:Journal)
WITH j LIMIT 10
WITH j, 
[pa=(j)<-[:BELONGS_TO]-(a:ArticleType) | pa] as pa, 
[po=(j)<-[:OWNS]-(o:JournalOwner) | po] as po,
[ps=(j)<-[:BELONGS_TO]-(s:Section) | ps] as ps,
[pf=(j)-[:ACCEPTS]->(f:FileCategory) | pf] as pf,
[pc=(j)-[:CHARGED_BY]->(apc:APC) | pc] as pc,
[pt=(j)-[:ACCEPTS]->(sft:SupportedFileType) | pt] as pt,
[pl=(j)<-[:BELONGS_TO|:CHILD_OF*..]-(c:Classification) | pl] as pl
RETURN pa, po, ps, pf, pc, pt, pl