带有附加type()运算符的WHERE NOT子句

时间:2017-10-29 20:43:44

标签: neo4j cypher

我正在尝试使用WHERE NOT和其他type()运算符编写查询。

这是一个正常的匹配,可以正常运行并返回2017年10月访问过俱乐部的用户。

MATCH (user:User)-[visited]->(club:Club) 
WHERE type(visited) >= "20171001" and type(visited) <= "20171031"
RETURN user;

这是一个没有正常工作的地方,并返回没有访问过俱乐部的用户。

MATCH (user:User) 
WHERE NOT ( (user:User)-[]->(:Club) ) RETURN user;

但我在格式化查询方面遇到了麻烦,导致2017年10月没有访问过俱乐部的用户返回。

MATCH (user:User) 
WHERE NOT ( (user:User)-[visited]->(:Club) 
AND type(visited) >= "20171001" and type(visited) <= "20171031")
RETURN user;

这将返回&#34;访问未定义&#34;错误。这似乎表明它需要在初始匹配中定义,但是将它添加到初始匹配中就像这样不返回任何记录,所以我被卡住了。

MATCH (user:User)-[visited]->(:Club) 
WHERE NOT ( (user:User)-[visited]->(:Club) 
AND type(visited) >= "20171001" and type(visited) <= "20171031")
RETURN user;

此评估,但不返回任何结果。问题在于它正在寻找被访问的关系,所以如果用户从未访问过俱乐部,他们就不会匹配,因此不会被拒绝作为没有访问过的用户。 10月访问。

2 个答案:

答案 0 :(得分:2)

这是使用OPTIONAL MATCH替代排除关系,然后只保留不存在这种关系的行的替代方法。

MATCH (user:User)
OPTIONAL MATCH (user)-[visited]->(:Club)
WHERE type(visited) STARTS WITH "201710"
WITH user
WHERE visited IS NULL
RETURN user

答案 1 :(得分:0)

正如您所观察到的那样,not possible to introduce new variables in the WHERE clause

  

请注意,您无法在此处引入新变量。

我认为最好的方法是列出10月份 访问俱乐部的用户,collect将他们列入一个列表,然后获取所有用户,并仅返回那些不在列表。

MATCH (user:User)-[visited]->(:Club)
WHERE type(visited) >= "20171001" AND type(visited) <= "20171031"
WITH collect(user) AS visitorsInOctober
MATCH (user:User)
WHERE NOT user IN visitorsInOctober
RETURN user

话虽如此,我相信您的数据模型应该得到改进。关系也可以具有属性,因此您可以使用类型VISITED和属性date来定义关系。这将导致类似于以下的查询:

MATCH (user:User)-[visited:VISITED]->(:Club)
WHERE visited.date >= "20171001" AND visited.date <= "20171031"
// ...