返回一个MATCH语句的多个关系计数

时间:2015-11-23 04:26:55

标签: neo4j cypher

我想做这样的事情:

MATCH (p:person)-[a:UPVOTED]->(t:topic),(p:person)-[b:DOWNVOTED]->(t:topic),(p:person)-[c:FLAGGED]->(t:topic) WHERE ID(t)=4 RETURN COUNT(a),COUNT(b),COUNT(c)

..但是当我得到2,1,1

时,我得到所有0个计数

3 个答案:

答案 0 :(得分:4)

更好的解决方案是使用<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" <Grid> <TabControl VerticalAlignment="Stretch" Grid.Column="0" Grid.Row="0"> <TabItem Header="First Tab" > <!-- This Tab will always load at first. --> </TabItem> <TabItem Header="Second Tab" > <!-- Items in this Tab should only load when Tab is selected--> </TabItem> </TabControl> </Grid> </Window> 来显着提高查询的性能:

size

如果你确定关系中的其他节点总是用Person标记,你可以从查询中删除它们,它会再快一点

答案 1 :(得分:0)

让我们开始重构一下查询(希望它的含义不会丢失):

MATCH
  (t:topic)
  (p:person)-[upvote:UPVOTED]-(t),
  (p:person)-[downvote:DOWNVOTED]->(t),
  (p:person)-[flag:FLAGGED]->(t)
WHERE ID(t)=4
RETURN COUNT(upvote), COUNT(downvote), COUNT(flag)

由于t是您的主要变量(因为您正在对其进行过滤),因此我与标签匹配一次,然后在其余匹配中仅使用变量。看到这样的查询被清理干净,在我看来,你正试图计算一个主题的所有upvotes / downvotes / flags,但你不关心是谁做了那些事情。目前,由于您使用相同的变量p Cypher将尝试匹配所有三行的同一个人。所以你可以有不同的变量:

 (p1:person)-[upvote:UPVOTED]-(t),
 (p2:person)-[downvote:DOWNVOTED]->(t),
 (p3:person)-[flag:FLAGGED]->(t)

或者更好,因为你没有引用其他地方的人,你可以把变量留下来:

(:person)-[upvote:UPVOTED]-(t),
(:person)-[downvote:DOWNVOTED]->(t),
(:person)-[flag:FLAGGED]->(t)

在风格上,我还建议您使用您要过滤的项目开始匹配:

(t)<-[upvote:UPVOTED]-(:person)    
(t)<-[downvote:DOWNVOTED]-(:person)    
(t)<-[flag:FLAGGED]-(:person)    

下一个问题是因为将这些问题设为MATCH,你说需要匹配。这意味着你永远不会得到带零的案例。所以你需要OPTIONAL MATCH

MATCH (t:topic)
WHERE ID(t)=4
OPTIONAL MATCH (t)<-[upvote:UPVOTED]-(:person)    
OPTIONAL MATCH (t)<-[downvote:DOWNVOTED]-(:person)    
OPTIONAL MATCH (t)<-[flag:FLAGGED]-(:person)    
RETURN COUNT(upvote), COUNT(downvote), COUNT(flag)

即便如此,尽管你所说的是:“找到一个主题并找到所有情况,其中有1个upvote,没有downvote,没有flag,1 upvote,1 downvote,no flag等等...所有排列)。这意味着你一次只想COUNT一个:

MATCH (t:topic)
WHERE ID(t)=4
OPTIONAL MATCH (t)<-[r:UPVOTED]-(:person)    
WITH t, COUNT(r) AS upvotes

OPTIONAL MATCH (t)<-[r:DOWNVOTED]-(:person)    
WITH t, upvotes, COUNT(r) AS downvotes

OPTIONAL MATCH (t)<-[r:FLAGGED]-(:person)    
RETURN upvotes, downvotes, COUNT(r) AS flags

一些杂项:

小心使用Neo ID作为长期参考,因为它们可以回收利用。

尽可能使用parameters来提高性能/安全性(WHERE ID(t)={topic_id}

此外,标签通常为TitleCase。请参阅The Zen of Cypher指南。

答案 2 :(得分:0)

检查此查询,我认为它会对您有所帮助。

&#13;
&#13;
MATCH (p:person)-[a:UPVOTED]->(t:topic),
(p)-[b:DOWNVOTED]->(t),(p)-[c:FLAGGED]->(t) 
WHERE ID(t)=4 
RETURN COUNT(a) as a_count,COUNT(b) as b_count,COUNT(c) as c_count;
&#13;
&#13;
&#13;