查找与节点列表有关系的节点

Find node that has relationships with a list of nodes

本文关键字:节点 有关系 列表 查找      更新时间:2023-09-26

假设我有节点USERs和节点CARs。它们可以通过关系LIKE连接。

我想通过USERs的给定列表返回所有LIKEdCARs

当前我有这个查询:

MATCH (c:CAR)<-[r:LIKES]-(u:User) 
WHERE u.username  IN ['Sara', 'John'] RETURN e, u

返回Sara, John或两者都喜欢的所有汽车。我想把它限制在只有双方都喜欢的汽车。

更新:这是我到目前为止想到的,但这种方法不允许我使用名称数组作为输入,我可以使用它,但我希望找到一个可以将数组作为参数的解决方案,任何帮助都非常感谢。

MATCH (c:CAR) 
WHERE (c)<-[:LIKES]-(:User {username: 'Sara'}) 
AND (e)<-[:LIKES]-(:User {username: 'John'}) 
return c

我想这个查询会满足你的需要:

MATCH (user:USER) WHERE user.username IN ['Sara', 'John']
WITH COLLECT(id(user)) AS user_ids
MATCH (user:USER)-[:LIKES]->(car:CAR)
WHERE id(user) IN user_ids
WITH car, user_ids, COLLECT(id(user)) as ids_of_users_that_like_car
WHERE ALL(user_id IN user_ids WHERE user_id IN ids_of_users_that_like_car) 
RETURN car

有点棘手。我发现最简单的方法是利用这个:

ALL(x IN y WHERE EXISTS(relationship))

假设萨拉、约翰和比尔的图表,其中三人都喜欢野马汽车,约翰和比尔喜欢Pintos,则此代码将返回野马汽车,这是列表中所有用户唯一喜欢的汽车:

WITH ['Sara', 'John', 'Bill'] AS usernames 
MATCH (c:CAR) 
WHERE ALL(username IN usernames WHERE EXISTS((:User{name:username})-[:LIKES]->(c))) 
RETURN c

编辑:或者,您可以尝试这样做,首先匹配列表中的用户,匹配这些用户喜欢的汽车,然后将其缩小到只有所有这些用户喜欢的汽车。

MATCH (u:User) WHERE u.name IN ['Sara', 'John', 'Bill'] 
WITH u, COLLECT(u) AS users
MATCH (u)-[:LIKES]->(c:CAR)
WHERE ALL(user IN users WHERE EXISTS((user)-[:LIKES]->(c))) 
RETURN c

您将需要在实际数据集上配置文件,以查看哪种效果最好。