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(过滤)、aggregate(reduce,聚合)或 transform(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 列表

有时你已将信息收集到列表中,但想将每个元素单独作为一行使用。例如,你可能想进一步匹配图中的模式。或者你传入了一组值,但现在想为每个元素创建一个或匹配一个节点或关系。这时,你可以使用 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
© . All rights reserved.