我正在尝试使用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月访问。
答案 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"
// ...