查找节点
创建电影图之后,我们可以查找演员和电影
寻找特定演员
如果你想在图中寻找特定的演员,可以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_IN 和 DIRECTED,这意味着 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"相关的人
如果你不知道 Person 和 Movie 节点之间通过什么关系连接,可以查询图来发现它们:
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(匹配)路径 ,并将其与相关的 Person 或 Movie 节点一起返回:
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;
字段访问、排序和分页
与其返回所有属性,不如过滤出你感兴趣的那些属性------例如 ProductName 和 UnitPrice。
在 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 WITH、CONTAINS 和 ENDS 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 中使用 sum、count、avg 和 max 等聚合函数。
如果你想查看某家公司(例如 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