首页 > 解决方案 > 返回与具有特定属性的其他节点的连接最多的节点

问题描述

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

(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 个。

我删除了消息变量以获取发送最多消息的 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)具有类别:'spam'的关系?

标签: neo4jcypher

解决方案


我认为你在正确的轨道上,你只是有点过于复杂了。您只需要对每个 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

推荐阅读