GraphGists

Cypher 可以开箱即用地创建和使用更复杂的数据结构。如前所述,您可以在语句中创建文字列表 ([1,2,3]) 和映射 ({name: value})。

有许多与列表一起使用的函数。它们从简单的函数(如返回列表大小的 size(list))到 reduce 函数(对元素运行表达式并累积结果)不等。

首先将一些数据加载到图中。

LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/intro/movies.csv" AS line
CREATE (m:Movie {id:line.id,title:line.title, released:toInt(line.year)});
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/intro/persons.csv" AS line
MERGE (a:Person {id:line.id}) ON CREATE SET a.name=line.name;
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/intro/roles.csv" AS line
MATCH (m:Movie {id:line.movieId})
MATCH (a:Person {id:line.personId})
CREATE (a)-[:ACTED_IN {roles:[line.role]}]->(m);
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/intro/movie_actor_roles.csv" AS line FIELDTERMINATOR ";"
MERGE (m:Movie {title:line.title}) ON CREATE SET m.released = toInt(line.released)
MERGE (a:Person {name:line.actor}) ON CREATE SET a.born = toInt(line.born)
MERGE (a)-[:ACTED_IN {roles:split(line.characters,",") }]->(m)

现在,让我们尝试使用数据结构。

首先,收集每部电影的演员姓名,并返回其中两个。

MATCH (movie:Movie)<-[:ACTED_IN]-(actor:Person)
RETURN movie.title as movie, collect(actor.name)[0..2] as two_of_cast

您还可以使用 list[1]list[5..-5] 快速访问列表的单个元素或切片。其他用于访问列表部分的函数有 head(list)tail(list)last(list)

列表谓词

在比较列表和数组时,您可以使用谓词,例如 value IN listany(x IN list WHERE x = value)。有一些列表谓词可以满足 allanynonesingle 元素的条件。

MATCH path = (:Person)-->(:Movie)<--(:Person)
WHERE any(n in nodes(path) WHERE n.name = 'Michael Douglas')
RETURN extract(n IN nodes(path)| coalesce(n.name, n.title))

列表处理

通常,您需要处理列表来 filter、聚合 (reduce) 或转换 (extract) 它们的值。这些转换可以在 Cypher 中完成,也可以在调用代码中完成。这种列表处理可以减少处理和返回的数据量,因此在 Cypher 语句中进行处理可能很有意义。

一个简单的非图形示例是

WITH range(1,10) as numbers
WITH extract(n in numbers | n*n) as squares
WITH filter(n in squares WHERE n > 25) as large_squares
RETURN reduce( a = 0, n in large_squares | a + n ) as sum_large_squares

在图形查询中,您可以过滤或聚合收集的值,也可以处理数组属性。

MATCH (m:Movie)<-[r:ACTED_IN]-(a:Person)
WITH m.title as movie, collect({name: a.name, roles: r.roles}) as cast
RETURN movie, filter(actor IN cast WHERE actor.name STARTS WITH "M")

展开列表

有时您已经将信息收集到一个列表中,但希望将每个元素分别用作一行。例如,您可能希望在图中进一步匹配模式。或者您传入了一组值,但现在希望为每个元素创建或匹配节点或关系。然后您可以使用 UNWIND 子句将列表重新展开成一系列行。

例如,一个查询可以找到前 3 位联合主演,然后跟踪他们的电影,并再次列出每部电影的演员阵容

MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:ACTED_IN]-(colleague:Person)
WHERE actor.name < colleague.name
WITH actor, colleague, count(*) AS frequency, collect(movie) AS movies
ORDER BY frequency DESC
LIMIT 3
UNWIND movies AS m
MATCH (m)<-[:ACTED_IN]-(a)
RETURN m.title AS movie, collect(a.name) AS cast