返回与具有特定属性的其他节点的连接最多的节点

时间:2019-10-26 15:09:44

标签: neo4j cypher

我的消息图中有以下关系:

(m:Message)-[:ORIGINATED_AT]->(i:IP)-[:IN_NETWORK]-(n:Network)

我正在尝试查找发送最多邮件类别为“垃圾邮件”的IP和网络。

我尝试了以下查询:

// IPs sending the most spam:
match (ip:IpAddress)--(m:Message)
where toLower(m.category) contains 'spam'
with ip, size(()-[:ORIGINATED_AT]->(ip)) as volume
ORDER BY volume DESC LIMIT 10
match (ip)--(net:Network)
return ip, net

,但似乎找到了“发送了最多邮件且包含至少一封垃圾邮件的网络”,但是我想要“发送了最多垃圾邮件的网络”。此外,查询返回的结果少于10个预期结果。

我删除了message变量以使IP发送最多的消息,这似乎按预期工作:

// IPs sending the most messages:
match (ip:IpAddress)
with ip, size(()-[:ORIGINATED_AT]->(ip)) as volume
ORDER BY volume DESC LIMIT 10
match (ip)--(net:Network)
return ip, net

如何修改查询以仅正确计算相关(m:Message)类别为“垃圾邮件”的关系?

1 个答案:

答案 0 :(得分:1)

我认为您走在正确的道路上,只是让它变得有些复杂。您只需要对每个IP地址中包含“垃圾邮件”的每封邮件进行计数汇总即可。

MATCH (ip:IpAddress)--(m:Message)
WHERE toLower(m.category) contains 'spam'
RETURN ip, count(m) AS spam_messages
ORDER BY spam_messages DESC LIMIT 10

要在这种情况下使用size(),请用不同的聚合函数count()替换collect(),该函数将元素放入列表或集合中,而不是对其进行计数。然后使用size()返回列表中的项目数。如果您以后需要某种形式的后期处理,那么这种方法将很有用。

MATCH (ip:IpAddress)--(m:Message)
WHERE toLower(m.category) contains 'spam'
WITH ip, collect(m) AS spam_messages
RETURN ip, size(spam_messages) as spam_messages_size
ORDER BY spam_messages_size DESC LIMIT 10