我有
在我的图表和下面的查询中导致了一个" Java堆空间"错误。
match (p1:Post)-[r1:TAGGED]->(t:Tag)<-[r2:TAGGED]-(p2:Post)
return p1.Title, count(r1), p2.Title, count(r2)
limit 10
我期望的是一些重复的行,具体取决于共享标签的数量。我不确定limit
将如何工作(在前10个帖子或标签后停止)。但是,因为我有limit 10
我不希望这个查询遍历所有图形。看起来确实如此。
通过一些更改,Christophe Willemsen的查询在15秒内返回10行。
// I need label for the otherPost because Users are also TAGGED
MATCH (post:Post)-[:TAGGED]->(t)<-[:TAGGED]-(otherPost:Post)
RETURN post.Title, count(t) as cnt, otherPost.Title
// ORDER BY cnt DESC // for now I do not need this
LIMIT 10;
我想&#34; ORDER BY&#34;子句可能导致遍历所有可能的路径,所以我删除了该条款,但它仍然是15秒。这也是15秒。当我在没有排序的情况下设定限值1或1000时。
我对Neo4j的期望是:&#34;从任何Post
节点开始,然后跳转到其标签并找到标有相同标签的其他邮件。当有10个发现停止遍历并返回结果时。&#34;我很确定它没有这样做。
为了明确我的期望,假设图表很小,我们在密码查询中使用Limit 3
。
p1 - [t1, t2, t3] // Post1 is tagged with t1, t2 and t3
p2 - [t2, t3, t4]
p3 - [t3, t4, t5]
我的期望是:
但是,在遍历所有数据后似乎应用了限制。
所以,我现在的问题是:Neo4j是否找到了所有的比赛并返回其中的10个或者在前10场比赛后停止搜索?当然,为什么?
在得到有用的答案之后,我设法缩小了我的问题的范围,所以我尝试了以下查询。
// 3 sec.
MATCH (p:Post)-[:TAGGED]->(t:Tag)
RETURN p.Title, count(t)
LIMIT 1;
// 3 sec.
MATCH (p:Post)-[:TAGGED]->(t:Tag)
RETURN p.Title, count(t)
LIMIT 1000;
// 100 ms.
MATCH (p:Post)-[:TAGGED]->(t:Tag)
RETURN p.Title, t.Name
LIMIT 1;
// 150 ms.
MATCH (p:Post)-[:TAGGED]->(t:Tag)
RETURN p.Title, t.Name
LIMIT 1000;
所以,我仍然不知道为什么,但是,使用聚合方法(我尝试collect(t.Name)
而不是count
)打破了limit
功能的预期(至少我的期望:)行为
答案 0 :(得分:6)
此查询将导致全局图表查找,至少对于neo4j 2.1.7及更低版本。
我首先匹配节点,然后扩展路径
MATCH (post:Post)
MATCH (post)-[:TAGS]->(t)<-[:TAGS]-(otherPost)
RETURN post, count(t) as cnt, otherPost
ORDER BY cnt DESC
LIMIT 10;
这是执行计划,正如您可以看到的那样,首先只匹配帖子节点(所以标签索引),只需要检索那些和以下关系
ColumnFilter
|
+Top
|
+EagerAggregation
|
+Filter
|
+SimplePatternMatcher
|
+NodeByLabel
+----------------------+--------+--------+----------------------------------------------+------------------------------------------------------------------------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+--------+--------+----------------------------------------------+------------------------------------------------------------------------------------------------+
| ColumnFilter | 10 | 0 | | keep columns post, cnt, otherPost |
| Top | 10 | 0 | | { AUTOINT0}; Cached( INTERNAL_AGGREGATEc24f01bf-69cc-4bd9-9aed-be257028194b of type Integer) |
| EagerAggregation | 9900 | 0 | | post, otherPost |
| Filter | 134234 | 0 | | NOT( UNNAMED30 == UNNAMED43) |
| SimplePatternMatcher | 134234 | 0 | t, UNNAMED43, UNNAMED30, post, otherPost | |
| NodeByLabel | 100 | 101 | post, post | :Post |
+----------------------+--------+--------+----------------------------------------------+------------------------------------------------------------------------------------------------+
Total database accesses: 101
这里有一篇博客文章,解释了除了查询的第一部分之外我删除标签的原因:http://graphaware.com/neo4j/2015/01/16/neo4j-graph-model-design-labels-versus-indexed-properties.html
答案 1 :(得分:2)
Christophe说和 尽量减少两者之间的基数:
match (p1:Post)-[r1:TAGGED]->(t:Tag)
WITH tag, count(*) as freq, collect(distinct p1.Title) as posts
MATCH (tag)<-[r2:TAGGED]-(p2:Post)
return posts, freq, p2.Title, count(r2)
limit 10