Cypher入门

查找节点

创建电影图之后,我们可以查找演员和电影

寻找特定演员

如果你想在图中寻找特定的演员,可以Match Person节点,并使用name属性来引用该演员

css 复制代码
MATCH (tom:Person {name:"Tom Hanks"})
RETURN tom

WHERE 子句引用的是你为 Person 节点设置的变量(tom),而不是节点标签

css 复制代码
MATCH (tom:Person {name:"Tom Hanks"})
RETURN tom

寻找特定电影

sql 复制代码
MATCH (cloudAtlas:Movie)
WHERE cloudAtlas.title = "Cloud Atlas"
RETURN cloudAtlas

相当于:

css 复制代码
MATCH(cloudAtlas: Movie {title: "Cloud Atlas"}) 
RETURN cloudAtlas;

限制返回结果

如果你想在没有特定顺序的情况下限制返回结果的数量,可以在RETURN子句中添加LIMIT。此查询将查找途中的所有Person节点,并使用Name属性返回其中的10个

less 复制代码
MATCH (p:Person)
RETURN p.name LIMIT 10

对于此查询,返回的是属性值,你只能以表格形式查看结果。

WHERE 子句

如果你想按特定属性返回节点,可以使用 WHERE 子句。你可以返回特定值(在本例中为在某一年发行的电影):

Cypher 复制代码
MATCH (nineties:Movie)
WHERE nineties.released = 1990
RETURN nineties.title

或者在一定范围内:

Cypher 复制代码
MATCH (nineties:Movie)
WHERE nineties.released > 1990 AND nineties.released < 2000
RETURN nineties.title

查找模式

在前面的步骤中,查询的是图中的节点。现在将通过查找图中的模式来检索相关的节点,即了解这些节点是如何相互关联的

汤姆·汉克斯的所有电影

要列出汤姆汉克斯参演的所有电影,你需要查询他的Person节点,以及它如何通过关系连接到Movie节点

cypher 复制代码
MATCH (tom:Person {name: "Tom Hanks"})-[r]->(tomHanksMovies:Movie)
RETURN tom,r,tomHanksMovies

汤姆·汉克斯的节点通过两种不同的关系连接到 Movie 节点:ACTED_INDIRECTED,这意味着 Person 节点既可以是演员,也可以是导演。

"Cloud Atlas"的导演

如前所述,可以通过Directed关系找到有关导演的信息:

css 复制代码
MATCH (cloudAtlas:Movie {title: "Cloud Atlas"})<-[:DIRECTED]-(directors)
RETURN directors.name

汤姆·汉克斯的联合主演

如果你想扩展模式并找到在同一部电影中合作过的演员,可以使用以下查询:

less 复制代码
MATCH (tom:Person {name:"Tom Hanks"})-[a:ACTED_IN]->(m:Movie)<-[b:ACTED_IN]-(coActors:Person)
RETURN tom, m, a, b, coActors

为了更好地理解上述查询,我们将其拆解。首先,查询找出汤姆·汉克斯参演了哪些电影:

css 复制代码
MATCH (tom:Person {name: "Tom Hanks"})-[a:ACTED_IN]->(m:Movie)

然后,找到在同一部电影中参演过的其他 Person 节点:

scss 复制代码
MATCH (m)<-[b:ACTED_IN]-(coActors:Person)

得到:

与"Cloud Atlas"相关的人

如果你不知道 PersonMovie 节点之间通过什么关系连接,可以查询图来发现它们:

scss 复制代码
MATCH (people:Person)-[relatedTo]-(:Movie {title: "Cloud Atlas"})
RETURN people.name, type(relatedTo), relatedTo

在此查询中,可以不指定关系和方向,由于未指定关系,可以用type()来检索关系类型

与凯文贝肯相关的电影和演员

"凯文·贝肯的六度分隔"游戏的前提是通过电影联合主演将任何演员与凯文贝肯联系起来,步数不超过六步。

可以使用两种不同的策略:

变长模式

此查询查找距离凯文贝肯一到三跳的所有Person和Movie节点:

css 复制代码
MATCH (bacon:Person {name:"Kevin Bacon"})-[*1..3]-(a:Person)
RETURN DISTINCT bacon, a

RETURN 子句包含一个 DISTINCT 运算符,以确保结果不会重复。在此查询中,凯文·贝肯可能在不同的电影中与同一位演员合作过,但此处只需要唯一的结果。

结果如下:

此查询的缺点是你不知道凯文·贝肯是如何 与这些人或电影建立联系的。如果你想检索连接这些节点的路径,请 MATCH(匹配)路径 ,并将其与相关的 PersonMovie 节点一起返回:

css 复制代码
MATCH p = (bacon:Person {name:"Kevin Bacon"})-[*1..3]-(a:Person)
RETURN DISTINCT bacon, a, p

p 变量指的是凯文·贝肯与他一到三跳内相关的 Person 节点之间的整条路径。然后 p 变量在 RETURN 子句中被引用。

现在结果中也包含了 Movie 节点,因为这就是凯文·贝肯与其他 Person 节点建立联系的方式。

shortestPath 算法

要找到两个演员之间的最短路径,请按如下方式使用该算法并返回路径:

css 复制代码
MATCH p=shortestPath(
  (bacon:Person {name:"Kevin Bacon"})-[*]-(meg:Person {name:"Meg Ryan"})
)
RETURN p

查询结果:

清理

完成实验之后,可以移除电影数据集并清洗Aura实例:

sql 复制代码
MATCH (n)
DETACH DELETE n

结果是以下消息:"Deleted 171 nodes, deleted 253 relationships"(已删除 171 个节点,已删除 253 条关系)。

验证图是否消失

如果你执行此查询来检索图中的所有节点并返回计数,你应该会看到返回的值为 0:

scss 复制代码
MATCH (n)
RETURN count(*)

Cypher 与 SQL 的对比

索引

SQL 和 Cypher 都提供了索引,使针对特定节点标签和属性组合的搜索更加高效

Cypher 中的索引仅用于查找查询的起点;所有后续的模式匹配均通过图结构完成。Cypher支持范围索引、文本索引、点索引、查找索引、全文索引和向量索引。

查询

选择并返回记录

SQL:

在 SQL 中,要选择并返回记录,需要从 products 表中选择所有内容。

css 复制代码
SELECT p.*
FROM products as p;

在 Cypher 中,你可以 MATCH(匹配)一个简单的模式:所有具有 :Product 标签 的节点,并 RETURN(返回)它们。

css 复制代码
MATCH (p:Product)
RETURN p;

字段访问、排序和分页

与其返回所有属性,不如过滤出你感兴趣的那些属性------例如 ProductNameUnitPrice

在 SQL 中,这是按价格排序并返回 10 个最昂贵条目的方法:

css 复制代码
SELECT p.ProductName, p.UnitPrice
FROM products as p
ORDER BY p.UnitPrice DESC
LIMIT 10;

Cypher 中的语句与此类似,区别仅在于模式匹配部分:

less 复制代码
MATCH (p:Product)
RETURN p.productName, p.unitPrice
ORDER BY p.unitPrice DESC
LIMIT 10;

按名称查找单个产品

有多种方法可以查询数据库并检索单个项目,例如名为 Chocolade 的产品。你可以通过相等性过滤来实现这一点。

在 SQL 中,你可以使用 WHERE 子句过滤数据:

css 复制代码
SELECT p.ProductName, p.UnitPrice
FROM products AS p
WHERE p.ProductName = 'Chocolade';

在 Cypher 中,WHERE 子句属于 MATCH 语句的一部分:

ini 复制代码
MATCH (p:Product)
WHERE p.productName = 'Chocolade'
RETURN p.productName, p.unitPrice;

一个更简短的选择是在 MATCH 语句中使用 productName 标签来指定产品:

css 复制代码
MATCH (p:Product {productName:'Chocolade'})
RETURN p.productName, p.unitPrice;

过滤

按列表/范围过滤

SQL: 在 SQL 中,你可以使用 IN 操作符:

less 复制代码
SELECT p.ProductName, p.UnitPrice
FROM products as p
WHERE p.ProductName IN ('Chocolade','Chai');

Cypher: Cypher 提供完整的集合支持,包括 IN 以及其他集合函数、谓词和转换:

less 复制代码
MATCH (p:Product)
WHERE p.productName IN ['Chocolade','Chai']
RETURN p.productName, p.unitPrice;
按多个数字和文本谓词过滤

此查询检索名称以 "C" 开头且价格大于 100 的产品:

css 复制代码
SELECT p.ProductName, p.UnitPrice
FROM products AS p
WHERE p.ProductName LIKE 'C%' AND p.UnitPrice > 100;

在 Cypher 中,LIKE 操作符被 STARTS WITHCONTAINSENDS WITH 操作符所取代:

less 复制代码
MATCH (p:Product)
WHERE p.productName STARTS WITH 'C' AND p.unitPrice > 100
RETURN p.productName, p.unitPrice;

你还可以使用正则表达式获取所有名称以 "C" 开头的产品及其价格:

less 复制代码
MATCH (p:Product)
WHERE p.productName =~ '^C.*'
RETURN p.productName, p.unitPrice

连接产品与客户

SQL

在 SQL 中,如果你想查看是谁购买了 Chocolade,可以将这四个表连接在一起:

vbnet 复制代码
SELECT DISTINCT c.CompanyName
FROM customers AS c
JOIN orders AS o ON (c.CustomerID = o.CustomerID)
JOIN order_details AS od ON (o.OrderID = od.OrderID)
JOIN products AS p ON (od.ProductID = p.ProductID)
WHERE p.ProductName = 'Chocolade';

Cypher

在 Cypher 中,无需使用 JOIN 连接表。你可以直接将连接表达为图模式

css 复制代码
MATCH (p:Product {productName:'Chocolade'})<-[:ORDERS]-(:Order)<-[:PURCHASED]-(c:Customer)
RETURN DISTINCT c.companyName;

每个产品的总支出

通过对产品价格和订购数量求和,可以提供每个客户针对各产品的汇总视图。你可以在 SQL 和 Cypher 中使用 sumcountavgmax 等聚合函数。

如果你想查看某家公司(例如 Drachenblut Delikatessen)在每个产品上的总支出(包括未订购某些产品的情况),你必须使用 OUTER JOIN,以确保即使在其他表中没有匹配行时也能返回结果。

sql 复制代码
SELECT p.Product_Name, sum(od.Unit_Price * od.Quantity) AS TotalPrice
FROM customers AS c
LEFT OUTER JOIN orders AS o ON (c.Customer_ID = o.Customer_ID)
LEFT OUTER JOIN order_details AS od ON (o.Order_ID = od.Order_ID)
LEFT OUTER JOIN products AS p ON (od.Product_ID = p.Product_ID)
WHERE c.Company_Name = 'Drachenblut Delikatessen'
GROUP BY p.Product_Name;

在 Cypher 中,你需要将 ORDERS 关系的 unitPrice 属性转换为整数,以便在订购数量和花费金额之间进行计算:

scss 复制代码
MATCH (p:Product)<-[o:ORDERS]-(order:Order)
SET o.unitPrice = toInteger(o.unitPrice)
RETURN o

然后,你 MATCH 你想要收集信息的公司,并使用 OPTIONAL MATCH 来查找他们的购买记录和获取的产品,最后 RETURN 总和:

scss 复制代码
MATCH (c:Customer {companyName:'Drachenblut Delikatessen'})
OPTIONAL MATCH (c)-[:PURCHASED]->(:Order)-[o:ORDERS]->(p:Product)
RETURN p.productName, toInteger(sum(o.unitPrice * o.quantity)) AS totalPrice
相关推荐
雪隐2 小时前
个人电脑玩AI-08让5060 Ti给你打工——我拿 Unlimited-OCR扫了 600 页书,然后悟了
人工智能·后端
AskHarries2 小时前
用 OpenClaw 做一份完整 PPT:从主题、提纲到 slide deck
后端·程序员
Csvn2 小时前
Linux 常用操作命令合集与运维实战
后端
卷无止境2 小时前
现代C++ 编译器生态及其对编程规范的影响
后端
云技纵横2 小时前
一个 @Async,把 @Transactional 的事务边界打穿了
后端·面试
BothSavage3 小时前
OpenHarness源码研究-3-codex配置到输出对话
后端·架构
SimonKing3 小时前
Google第三方授权登录
java·后端·程序员
codingWhat3 小时前
能效平台设计方案(打通gitlab和飞书)
后端·node.js·koa