教程目录 引自:https://neo4j.com/docs/getting-started/cypher-intro/large-statements/
编写大型语句
示例图
我们继续使用与之前相同的示例数据:
CREATE (matrix:Movie {title: 'The Matrix', released: 1997})
CREATE (cloudAtlas:Movie {title: 'Cloud Atlas', released: 2012})
CREATE (forrestGump:Movie {title: 'Forrest Gump', released: 1994})
CREATE (keanu:Person {name: 'Keanu Reeves', born: 1964})
CREATE (robert:Person {name: 'Robert Zemeckis', born: 1951})
CREATE (tom:Person {name: 'Tom Hanks', born: 1956})
CREATE (tom)-[:ACTED_IN {roles: ['Forrest']}]->(forrestGump)
CREATE (tom)-[:ACTED_IN {roles: ['Zachry']}]->(cloudAtlas)
CREATE (robert)-[:DIRECTED]->(forrestGump)
这是生成的图:
(插入图表链接)
图 1. 电影图
UNION
如果要组合具有相同结果结构的两个语句的结果,可以使用 UNION [ALL]
。
例如,以下查询列出了演员和导演:
MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN actor.name AS name, type(r) AS type, movie.title AS title
UNION
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN director.name AS name, type(r) AS type, movie.title AS title
Rows: 3
+-------------------------------------------------+
| name | type | title |
+-------------------------------------------------+
| 'Tom Hanks' | 'ACTED_IN' | 'Cloud Atlas' |
| 'Tom Hanks' | 'ACTED_IN' | 'Forrest Gump' |
| 'Robert Zemeckis' | 'DIRECTED' | 'Forrest Gump' |
+-------------------------------------------------+
请注意,返回的列必须在所有子句中以相同的方式设置别名。
上面的查询等效于这个更紧凑的查询:
MATCH (actor:Person)-[r:ACTED_IN|DIRECTED]->(movie:Movie)
RETURN actor.name AS name, type(r) AS type, movie.title AS title
WITH
在 Cypher® 中,您可以将语句片段链接在一起,类似于在数据流管道中完成的方式。每个片段都处理前一个片段的输出,并且其结果可以馈送到下一个片段中。只有在 WITH
子句中声明的列才在后续查询部分中可用。
WITH
子句用于组合各个部分并声明数据从一个部分流向另一个部分。WITH
类似于 RETURN
子句。不同之处在于 WITH
子句不会完成查询,而是为下一部分准备输入。表达式、聚合、排序和分页可以以与 RETURN
子句相同的方式使用。唯一的区别是所有列都必须设置别名。
在以下示例中,收集某人出演的电影,然后过滤掉仅出现在一部电影中的电影。
MATCH (person:Person)-[:ACTED_IN]->(m:Movie)
WITH person, count(*) AS appearances, collect(m.title) AS movies
WHERE appearances > 1
RETURN person.name, appearances, movies
Rows: 1
+-------------------------------------------------------------+
| person.name | appearances | movies |
+-------------------------------------------------------------+
| 'Tom Hanks' | 2 | ['Cloud Atlas', 'Forrest Gump'] |
+-------------------------------------------------------------+
使用 WITH
子句,您可以将值从查询的一部分传递到另一部分。这允许您在查询中执行一些中间计算或操作以供以后使用。
以下数据集用于演示下面的示例:
(插入图表链接)
图 2. 图:人员、他们喜欢的技术以及他们工作的公司
要重现该图,请运行 Cypher 代码:
CREATE (diana:Person {name: "Diana"})
CREATE (melissa:Person {name: "Melissa", twitter: "@melissa"})
CREATE (dan:Person {name: "Dan", twitter: "@dan", yearsExperience: 6})
CREATE (sally:Person {name: "Sally", yearsExperience: 4})
CREATE (john:Person {name: "John", twitter: "@jennifer", yearsExperience: 5})
CREATE (joe:Person {name: "Joe"})
CREATE (mark:Person {name: "Mark", twitter: "@mark"})
CREATE (ann:Person {name: "Ann"})
CREATE (xyz:Company {name: "XYZ"})
CREATE (x:Company {name: "Company X"})
CREATE (a:Company {name: "Company A"})
CREATE (Neo4j:Company {name: "Neo4j"})
CREATE (abc:Company {name: "ABC"})
CREATE (query:Technology {type: "Query Languages"})
CREATE (etl:Technology {type: "Data ETL"})
CREATE (integrations:Technology {type: "Integrations"})
CREATE (graphs:Technology {type: "Graphs"})
CREATE (dev:Technology {type: "Application Development"})
CREATE (java:Technology {type: "Java"})
CREATE (diana)-[:LIKES]->(query)
CREATE (melissa)-[:LIKES]->(query)
CREATE (dan)-[:LIKES]->(etl)<-[:LIKES]-(melissa)
CREATE (xyz)<-[:WORKS_FOR]-(sally)-[:LIKES]->(integrations)<-[:LIKES]-(dan)
CREATE (sally)<-[:IS_FRIENDS_WITH]-(john)-[:LIKES]->(java)
CREATE (john)<-[:IS_FRIENDS_WITH]-(jennifer)-[:LIKES]->(java)
CREATE (john)-[:WORKS_FOR]->(xyz)
CREATE (sally)<-[:IS_FRIENDS_WITH]-(jennifer)-[:IS_FRIENDS_WITH]->(melissa)
CREATE (joe)-[:LIKES]->(query)
CREATE (x)<-[:WORKS_FOR]-(diana)<-[:IS_FRIENDS_WITH]-(joe)-[:IS_FRIENDS_WITH]->(mark)-[:LIKES]->(graphs)<-[:LIKES]-(jennifer)-[:WORKS_FOR]->(Neo4j)
CREATE (ann)<-[:IS_FRIENDS_WITH]-(jennifer)-[:IS_FRIENDS_WITH]->(mark)
CREATE (john)-[:LIKES]->(dev)<-[:LIKES]-(ann)-[:IS_FRIENDS_WITH]->(dan)-[:WORKS_FOR]->(abc)
CREATE (ann)-[:WORKS_FOR]->(abc)
CREATE (a)<-[:WORKS_FOR]-(melissa)-[:LIKES]->(graphs)<-[:LIKES]-(diana)
您必须在 WITH
子句中指定您以后要使用的变量。只有这些变量会传递到查询的下一部分。有多种方法可以使用此功能(例如,计数、收集、过滤、限制结果)。
有关如何使用 WITH
的更多信息,请参阅 Cypher 手册部分。
//Query1: find and list the technologies people like
MATCH (a:Person)-[r:LIKES]-(t:Technology)
WITH a.name AS name, collect(t.type) AS technologies
RETURN name, technologies;
Query1 结果:
Rows: 9
+----------------------------------------------------------+
| name | technologies |
+----------------------------------------------------------+
| 'Sally' | ['Integrations'] |
| 'Dan' | ['Data ETL', 'Integrations'] |
| 'John' | ['Java', 'Application Development'] |
| 'Diana' | ['Query Languages', 'Graphs'] |
| 'Jennifer' | ['Java', 'Graphs'] |
| 'Ann' | ['Application Development'] |
| 'Mark' | ['Graphs'] |
| 'Joe' | ['Query Languages'] |
| 'Melissa' | ['Query Languages', 'Data ETL', 'Graphs'] |
+----------------------------------------------------------+
//Query2: find number of friends who have other friends
MATCH (p:Person)-[:IS_FRIENDS_WITH]->(friend:Person)
WITH p, collect(friend.name) AS friendsList, count{(friend)-[:IS_FRIENDS_WITH]-(:Person)} AS numberOfFoFs
WHERE numberOfFoFs > 1
RETURN p.name, friendsList, numberOfFoFs;
Query2 结果:
Rows: 3
+---------------------------------------------------+-----------------+
| p.name | friendList | numberOfFoFs |
+---------------------------------------------------+-----------------+
| 'Joe' | ['Mark'] | 2 |
| 'Jennifer' | ['Sally', 'John', 'Ann', 'Mark'] | 2 |
| 'John' | ['Sally'] | 2 |
+---------------------------------------------------+-----------------+
在第一个查询中,传递了人员姓名和收集的技术类型列表。因此,只有这些项目可以在 RETURN
子句中引用。关系 ® 和人员出生日期都不能使用,因为这些值没有传递。
在第二个查询中,只能引用 p 及其任何属性(姓名、出生日期、工作年限、Twitter)、朋友的集合(作为一个整体,而不是每个值)以及朋友的朋友的数量。由于这些值已在 WITH
子句中传递,因此可以在 WHERE
或 RETURN
子句中使用它们。
WITH
要求传递的所有值都具有变量(如果它们还没有变量)。Person
节点在 MATCH
子句中被赋予变量 §,因此不需要在那里分配变量。
WITH
对于在查询之前设置参数也非常有用。在导入数据时,通常对参数键、URL 字符串和其他查询变量很有用。
//Find people with 2-6 years of experience
WITH 2 AS experienceMin, 6 AS experienceMax
MATCH (p:Person)
WHERE experienceMin <= p.yearsExperience <= experienceMax
RETURN p