构建大型语句
示例图
我们继续使用之前相同的示例数据
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)
这是生成的图
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' | +-------------------------------------------------+
请注意,所有子句中返回的列必须以相同的方式别名。
以上查询等效于以下更紧凑的查询
|
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
子句,您可以将值从查询的一个部分传递到另一个部分。这允许您在查询中执行一些中间计算或操作,以便以后使用。
以下数据集用于演示下面的示例
要重现该图,请运行 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", yearsExperience: 5})
CREATE (jennifer:Person {name: "Jennifer", 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;
查询 1 结果
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;
查询 2 结果
Rows: 3 +---------------------------------------------------+-----------------+ | p.name | friendList | numberOfFoFs | +---------------------------------------------------+-----------------+ | 'Joe' | ['Mark'] | 2 | | 'Jennifer' | ['Sally', 'John', 'Ann', 'Mark'] | 2 | | 'John' | ['Sally'] | 2 | +---------------------------------------------------+-----------------+
在第一个查询中,传递了 Person
名称和 Technology
类型的已收集列表。因此,只有这些项目可以在 RETURN
子句中引用。关系 (r
) 或 Person
出生日期都不能使用,因为这些值没有传递。
在第二个查询中,只能引用 p
及其任何属性 (name
、birthdate
、yearsExperience
、twitter
)、朋友的集合(作为一个整体,而不是每个值)以及朋友的朋友的数量。由于这些值已在 WITH
子句中传递,因此可以在 WHERE
或 RETURN
子句中使用它们。
WITH
要求所有传递的值都具有变量(如果它们还没有变量)。Person
节点在 MATCH
子句中被赋予一个变量 (p
),因此无需在那里分配变量。
|