给定一个描述社交网络的图表,任何人都可以在其中 post 编写一个查询,查找 Dani 的所有 3 级以下的朋友,他们也标记了喜欢
Given a graph depicting a social network where anyone can also post Write a query that finds all of Dani's friends up to level 3 who also marked likes
给定一张描绘社交网络的图表,任何人都可以在其中 post。
一个用户可以是别人的朋友,也可以只是喜欢他的post。
关系类型有:朋友、喜欢、发布
顶点类型:人物,post
一个人有以下数据:姓名、年龄、性别
Post 有以下数据:标题、日期、内容
Write a query that finds all of Dani's friends up to level 3 who also
marked likes on all the posts he wrote and are older than him
尝试:
MATCH (c:person) with COLLECT(c) AS persons
MATCH (s:friend {name:"Dani"}) WHERE ALL (x IN persons WHERE (s)-[:friend*1..3])
and c.age > dani.age
我尝试在 google 上搜索如何进行双重匹配的语法有误,我为此苦苦挣扎,对我来说最难的是匹配所有喜欢的朋友 post Dani 的文章像问题所要求的那样发表。
谢谢。
欢迎使用 Epsilon 1!
编辑:Dani 未发布任何内容的支持案例:
你可以这样做:
MATCH (d:person{name:'Dani'})-[:friend*..3]-(friend:person)
WHERE friend.age > d.age
WITH d, collect(friend) AS friends
OPTIONAL MATCH (d)-[:publish]->(p:post)
WITH COUNT(p) AS countP, d, friends
OPTIONAL MATCH (d)-[:publish]->(:post)<-[:likes]-(lp:person)
WITH DISTINCT(lp) AS likePeople, COUNT(lp) AS likesCount, d, countP, friends
WHERE likesCount=countP AND (likePeople IN friends OR likePeople IS NULL)
RETURN CASE WHEN likePeople IS NOT NULL THEN likePeople ELSE friends END AS friends
其中使用此示例数据:
MERGE (a:person{name: 'Dani', age: 12})
MERGE (b:person{name: 'B', age: 13})
MERGE (c:person{name: 'C', age: 11})
MERGE (d:person{name: 'D', age: 13})
MERGE (e:person{name: 'E', age: 13})
MERGE (f:post{key: 2})
MERGE (g:post{key: 3})
MERGE (h:post{key: 4})
MERGE (i:person{name: 'I', age: 13})
MERGE (j:person{name: 'J', age: 13})
MERGE (k:post{key: 7})
MERGE (l:post{key: 8})
MERGE (m:post{key: 9})
MERGE (a)-[:publish]-(f)
MERGE (a)-[:publish]-(g)
MERGE (a)-[:publish]-(h)
MERGE (b)-[:publish]-(k)
MERGE (b)-[:publish]-(l)
MERGE (d)-[:publish]-(m)
MERGE (e)-[:likes]-(f)
MERGE (e)-[:likes]-(g)
MERGE (e)-[:likes]-(h)
MERGE (d)-[:likes]-(f)
MERGE (c)-[:likes]-(g)
MERGE (d)-[:likes]-(h)
MERGE (e)-[:likes]-(h)
MERGE (j)-[:likes]-(f)
MERGE (j)-[:likes]-(g)
MERGE (j)-[:likes]-(h)
MERGE (a)-[:friend]-(b)
MERGE (b)-[:friend]-(c)
MERGE (c)-[:friend]-(d)
MERGE (d)-[:friend]-(e)
MERGE (d)-[:friend]-(a)
MERGE (i)-[:friend]-(j)
MERGE (i)-[:friend]-(c)
会 return:
╒═════════════════════╕
│"friend" │
╞═════════════════════╡
│{"name":"E","age":13}│
└─────────────────────┘
首先我们统计 Dani 的 posts
published
的数量,然后我们找到所有 persons
谁 liked
其中一些并只保留 persons
谁喜欢我们在第一步 (countP) 中找到的 posts
的数量。
然后我们找到距离最多为 3 的所有朋友,并仅保留上一步列表中的那些朋友(例如 People),并且他们的 age
大于 Dani 的。
MATCH
步骤之间的 WITH
允许查询继续使用以前的结果。
编辑:我更新了答案以支持 Dani 未发布任何内容的情况。在这种情况下,结果将是他的所有朋友,最多 3 个级别,比他大。这个边缘案例让我可以解释 OPTIONAL MATCH
的本质。当删除 OPTIONAL
时,查询将 return 没有朋友,因为它在第二个 MATCH
上什么也找不到。如果你确实想支持 Dani 不发布的情况,OPTIONAL
允许在没有结果的情况下使用 null 继续查询,在我们的情况下,允许我们 return 朋友。
给定一张描绘社交网络的图表,任何人都可以在其中 post。
一个用户可以是别人的朋友,也可以只是喜欢他的post。
关系类型有:朋友、喜欢、发布
顶点类型:人物,post
一个人有以下数据:姓名、年龄、性别
Post 有以下数据:标题、日期、内容
Write a query that finds all of Dani's friends up to level 3 who also marked likes on all the posts he wrote and are older than him
尝试:
MATCH (c:person) with COLLECT(c) AS persons
MATCH (s:friend {name:"Dani"}) WHERE ALL (x IN persons WHERE (s)-[:friend*1..3])
and c.age > dani.age
我尝试在 google 上搜索如何进行双重匹配的语法有误,我为此苦苦挣扎,对我来说最难的是匹配所有喜欢的朋友 post Dani 的文章像问题所要求的那样发表。
谢谢。
欢迎使用 Epsilon 1! 编辑:Dani 未发布任何内容的支持案例:
你可以这样做:
MATCH (d:person{name:'Dani'})-[:friend*..3]-(friend:person)
WHERE friend.age > d.age
WITH d, collect(friend) AS friends
OPTIONAL MATCH (d)-[:publish]->(p:post)
WITH COUNT(p) AS countP, d, friends
OPTIONAL MATCH (d)-[:publish]->(:post)<-[:likes]-(lp:person)
WITH DISTINCT(lp) AS likePeople, COUNT(lp) AS likesCount, d, countP, friends
WHERE likesCount=countP AND (likePeople IN friends OR likePeople IS NULL)
RETURN CASE WHEN likePeople IS NOT NULL THEN likePeople ELSE friends END AS friends
其中使用此示例数据:
MERGE (a:person{name: 'Dani', age: 12})
MERGE (b:person{name: 'B', age: 13})
MERGE (c:person{name: 'C', age: 11})
MERGE (d:person{name: 'D', age: 13})
MERGE (e:person{name: 'E', age: 13})
MERGE (f:post{key: 2})
MERGE (g:post{key: 3})
MERGE (h:post{key: 4})
MERGE (i:person{name: 'I', age: 13})
MERGE (j:person{name: 'J', age: 13})
MERGE (k:post{key: 7})
MERGE (l:post{key: 8})
MERGE (m:post{key: 9})
MERGE (a)-[:publish]-(f)
MERGE (a)-[:publish]-(g)
MERGE (a)-[:publish]-(h)
MERGE (b)-[:publish]-(k)
MERGE (b)-[:publish]-(l)
MERGE (d)-[:publish]-(m)
MERGE (e)-[:likes]-(f)
MERGE (e)-[:likes]-(g)
MERGE (e)-[:likes]-(h)
MERGE (d)-[:likes]-(f)
MERGE (c)-[:likes]-(g)
MERGE (d)-[:likes]-(h)
MERGE (e)-[:likes]-(h)
MERGE (j)-[:likes]-(f)
MERGE (j)-[:likes]-(g)
MERGE (j)-[:likes]-(h)
MERGE (a)-[:friend]-(b)
MERGE (b)-[:friend]-(c)
MERGE (c)-[:friend]-(d)
MERGE (d)-[:friend]-(e)
MERGE (d)-[:friend]-(a)
MERGE (i)-[:friend]-(j)
MERGE (i)-[:friend]-(c)
会 return:
╒═════════════════════╕
│"friend" │
╞═════════════════════╡
│{"name":"E","age":13}│
└─────────────────────┘
首先我们统计 Dani 的 posts
published
的数量,然后我们找到所有 persons
谁 liked
其中一些并只保留 persons
谁喜欢我们在第一步 (countP) 中找到的 posts
的数量。
然后我们找到距离最多为 3 的所有朋友,并仅保留上一步列表中的那些朋友(例如 People),并且他们的 age
大于 Dani 的。
MATCH
步骤之间的 WITH
允许查询继续使用以前的结果。
编辑:我更新了答案以支持 Dani 未发布任何内容的情况。在这种情况下,结果将是他的所有朋友,最多 3 个级别,比他大。这个边缘案例让我可以解释 OPTIONAL MATCH
的本质。当删除 OPTIONAL
时,查询将 return 没有朋友,因为它在第二个 MATCH
上什么也找不到。如果你确实想支持 Dani 不发布的情况,OPTIONAL
允许在没有结果的情况下使用 null 继续查询,在我们的情况下,允许我们 return 朋友。