我是 Neo4J Cypher 的新手,我知道我想在 SQL 中得到什么,但无法在 Cypher 中创建查询。
我们有3张桌子:
Pers(persId,name,workId,born)
Work(workId,name)
Friend(pers1Id,pers2Id)
问题: 寻找在同一家公司工作且不是朋友并且年龄相差小于5的人。 在 SQL 中,一个简单的查询如下所示:
select * from Pers p1 join Pers p2 on p1.workId=p2.workId
where not exists
(select 1 from Friend f where p1.persId in (f.person1Id,f.person2Id)
and p2.persId in (f.person1Id,f.person2Id) )
and abs(p1.born-p2.born)<5
Neo4J Cypher 怎么样? 任何帮助将不胜感激,特别是如何将 SQL 转换为 Cypher 查询。 米雷克
假设您有 :Person 和 :Workplace 标签。让我们假设这些类型的关系已经存在:
(:Person)-[:WorksAt]->(:Workplace)
(:Person)-[:FriendsWith]->(:Person)
您的 Cypher 查询将类似于:
MATCH (p1:Person)-[:WorksAt]->()<-[:WorksAt]-(p2:Person)
WHERE NOT (p1)-[:FriendsWith]-(p2)
AND abs(p1.born-p2.born) < 5
RETURN p1, p2
但请记住,我认为每次配对您将获得两行,并且顺序交换(如果您需要,我们可以毫不费力地消除它)。
一般来说,画出模式或查询的图表是个好主意,从那里将其转换为 Cypher 通常并不难。
正如 InverseFalcon 的答案所示,您可以使用
WHERE NOT <pattern>
构造来表达反连接(有时称为左反半连接)操作。
我刚刚完成了一篇关于该主题的学术论文 - 该论文目前正在接受同行评审,但它可以帮助您理解关系代数和 Cypher 之间的联系:http://docs.inf.mit.bme.hu/ingraph/ pub/btw2017-openencypher.pdf