Neo4j使用记录--基础篇(Cypher)【语法】

引言

日常我们在创建知识图谱的时候,入门的图数据库几乎为Neo4j数据库,Cypher 是图形数据库 Neo4j 的查询语言。我们要掌握Neo4j数据库,必须掌握Cypher语言。以下是我个人学习中的记录,恭请指教!!

Cypher–简介

Cypher 受到不同方法的启发,如 WHERE ORDER BY 受到了 SQL 的启发,模式匹配则借用了 SPARQL 的表达式方法,一些列表语义借用了 Haskell 和 Python 等语言,正则表达式匹配实现实用Scala programming language语言。

  1. Cypher 的构造基于英文散文和简洁的图像,基于英语单词和灵巧的图解,使查询易于编写和阅读。
  2. Cypher是一个描述性的图形查询语言,允许不必编写图形结构的遍历代码对图形存储有表现力和效率的查询。
  3. Cypher设计的目的是一个人类查询语言,适合于开发者和在数据库上做点对点模式(ad-hoc)查询的专业操作人员。
  4. Cypher是一个申明式的语言。对比命令式语言如Java和脚本语言如Gremlin和JRuby,它的焦点在于从图中如何找回(what to retrieve),而不是怎么去做。这使得在不对用户公布的实现细节里关心的是怎么优化查询。

Cypher–能力

Cypher具备的能力:

  • Cypher通过模式匹配图数据库中的节点和关系,来提取信息或者修改数据。
  • Cypher语句中允许使用变量,用来表示命名、绑定元素和参数。
  • Cypher语句可以对节点、关系、标签和属性进行创建、更新和删除操作。
  • Cypher语句可以管理索引和约束。

Cypher–语法

  1. 节点语法:采用一对圆括号来表示节点。如:()、(foo)
  2. 关系语法:使用一对短横线表示无方向关系,有方向加箭头。如:-[role]-、-[:ACTED_IN]->、-[role:ACTED_IN]->
  3. 模式语法:将节点和关系的语法组合在一起可以表达模式。如:(keanu: Person: Actor {name: “Keanu Rteves”}-[role:ACTED_IN {roles: [“Neo”]}]->{matrix: Movie {title: “The Matrix”}})

Cypher–数值类型

数值、字符串、布尔、节点、关系、路径、映射(Map)、列表(List)

Cypher–函数:

断言(Predicate)函数、标量(Scalar)函数、列表(List)函数、数学(Math)函数、字符串(String)函数、自定义函数

函数 函数 函数
标量(Scalar)函数 列表(List)函数 数学(Math)函数
字符串(String)函数 断言(Predicate)函数 自定义函数

查询语法

筛选查询

查看数据Schema表结构

CALL db.schema.visualization()

查看节点属性类型

CALL db.schema.nodeTypeProperties()
CALL apoc.meta.nodeTypeProperties()

查看关系属性类型

CALL db.schema.relTypeProperties()

查看关系图中的唯一性约束索引

SHOW CONSTRAINTS

基本查询

基本语法

查询另一端节点标签

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(p)
WHERE  p.born.year > 1960
RETURN p.name, p.born, labels(p), m.title

查询关系类型

MATCH (p:Person)-[r]->(m:Movie)
WHERE  p.name = 'Tom Hanks'
RETURN m.title AS movie, type(r) AS relationshipType

查询是否在列表属性中

MATCH (m:Movie)
WHERE "Israel" IN m.countries
RETURN m.title, m.languages, m.countries

查询属性是否存在

IS NULL IS NOT NULL

MATCH (p:Person)
WHERE p.died IS NULL
AND p.born.year <= 1922
RETURN p.name, p.born, p.died

大小写开头

统一大小写 都大写、以什么开头
MATCH (m:Movie)
WHERE toUpper(m.title) STARTS WITH 'LIFE IS'
RETURN m.title
统一大小写 都小写、包含谓词
MATCH (p:Person)-[r]->(m:Movie)
WHERE toLower(r.role) CONTAINS "dog"
RETURN p.name, r.role, m.title

判断是否存在

是否存在,存在,返回改行exists
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE  p.name = 'Tom Hanks'
AND exists {(p)-[:DIRECTED]->(m)}
RETURN p.name, labels(p), m.title

返回结果的查询操作

使用关键字查询模式和性能分析

PROFILE

关键字显示从查询中的图形中检索到的总行数

PROFILE MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE  p.name = 'Tom Hanks'
AND exists {(p)-[:DIRECTED]->(m)}
RETURN m.title

OPTIONAL MATCH

将模式与图形匹配,就像这样。不同之处在于,如果未找到匹配项,则将使用 null 来表示模式的缺失部分。

MATCH (m:Movie) WHERE m.title = "Kiss Me Deadly"
MATCH (m)-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(rec:Movie)
OPTIONAL MATCH (m)<-[:ACTED_IN]-(a:Actor)-[:ACTED_IN]->(rec)
RETURN rec.title, a.name

ORDER BY

返回的结果排序 降序 ORDER BY ... DESC 默认升序 ORDER BY ... ASC

MATCH (m:Movie)<-[ACTED_IN]-(p:Person)
WHERE m.imdbRating IS NOT NULL
RETURN m.title, m.imdbRating, p.name, p.born
ORDER BY m.imdbRating DESC, p.born DESC

SKIP LIMIT

返回结果跳过或者限制数量

MATCH (p:Person)
WHERE p.born.year = 1980
RETURN  p.name as name,
p.born AS birthDate
ORDER BY p.born SKIP 40 LIMIT 10

DISTINCT

返回结果 去重

MATCH (p:Person)-[:DIRECTED | ACTED_IN]->(m:Movie)
WHERE p.name = 'Tom Hanks'
RETURN DISTINCT m.title, m.released
ORDER BY m.title

{.··, .··}

返回数据以节点的JSON样式

MATCH (p:Person)
WHERE p.name CONTAINS "Thomas"
RETURN p { .* } AS person
ORDER BY p.name ASC
// 自定义在对象中返回的属性
MATCH (p:Person)
WHERE p.name CONTAINS "Thomas"
RETURN p { .name, .born } AS person
ORDER BY p.name
// 向返回的对象数据添加信息 如例:加favorite属性
MATCH (m:Movie)<-[:DIRECTED]-(d:Director)
WHERE d.name = 'Woody Allen'
RETURN m {.*, favorite: true} AS movie

结果数据运算

返回的数据进行运算

MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE m.title CONTAINS 'Toy Story' AND
p.died IS NULL
RETURN 'Movie: ' + m.title AS movie,
p.name AS actor,
p.born AS dob,
date().year - p.born.year AS ageThisYear

CASE ... END

返回的结果进行条件更改

// 转换返回的数据以反映电影的时间范围
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Henry Fonda'
RETURN m.title AS movie,
CASE
WHEN m.year < 1940 THEN 'oldies'
WHEN 1940 <= m.year < 1950 THEN 'forties'
WHEN 1950 <= m.year < 1960 THEN 'fifties'
WHEN 1960 <= m.year < 1970 THEN 'sixties'
WHEN 1970 <= m.year < 1980 THEN 'seventies'
WHEN 1980 <= m.year < 1990 THEN 'eighties'
WHEN 1990 <= m.year < 2000 THEN 'nineties'
ELSE  'two-thousands'
END
AS timeFrame
// 第二个例子
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE m.title CONTAINS 'Toy Story'
RETURN m.title AS movie,
p.name AS actor,
p.born AS dob,
CASE 
WHEN p.died IS NULL THEN date().year - p.born.year WHEN p.died IS NOT NULL THEN "Died" END
AS ageThisYear

节点数据操作

聚合

公式 含义
MAX() 最大值
min() 最小值
avg() 均值
stddev() 标准差
sum() 求和

统计

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(d:Person)
RETURN a.name, d.name,
count(*) AS numMovies
ORDER BY numMovies DESC

返回列表

MATCH (p:Person)
RETURN p.name, [p.born, p.died] AS lifeTime
LIMIT 10

返回结果创建列表

collect 将值聚合到列表中。该值可以是任何表达式,例如属性值、节点或函数或操作的结果

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN a.name AS actor,
count(*) AS total,
collect(m.title) AS movies
ORDER BY total DESC LIMIT 10

消除列表中的重复值

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
WHERE m.year = 1920
RETURN  collect( DISTINCT m.title) AS movies,
collect( a.name) AS actors

访问列表元素 head() tail

// 返回列表中元素的第一个值
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title AS movie,
collect(a.name)[0] AS castMember,
size(collect(a.name)) as castSize
// 从第二个返回列表元素
MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title AS movie,
collect(a.name)[2..] AS castMember,
size(collect(a.name)) as castSize

统计返回列表值得数据 size()

//Query 1  profile 测试查询性能
PROFILE MATCH (g:Genre)<-[:IN_GENRE]-(m)
RETURN g.name AS genre,
size(collect(m)) AS numMovies
ORDER BY size(collect(m)) DESC

结果进行列表查询

MATCH (m:Movie)
RETURN m.title as movie,
[x IN m.countries WHERE x = 'USA' OR x = 'Germany']
AS country LIMIT 500

模式列表查询

指定带有方括号的列表,以包含图案后跟管道字符,然后指定将在模式列表中放置的值。

MATCH (m:Movie)
WHERE m.year = 2015
RETURN m.title,
[(dir:Person)-[:DIRECTED]->(m) | dir.name] AS directors,
[(actor:Person)-[:ACTED_IN]->(m) | actor.name] AS actors

模式理解的另一个实例

// 电影的标题与电影年份连接,作为要添加的值作为返回的列表的元素。
MATCH (a:Person {name: 'Tom Hanks'})
RETURN 
[(a)-->(b:Movie) WHERE b.title CONTAINS "Toy" | b.title + ": " + b.year] AS movies

日期查询

确定两个日期时间值之间的差异

// 返回一个持续时间值,该值表示两个值之间的天数和月数以及时间
MATCH (x:Test {id: 1})
RETURN duration.between(x.date1,x.date2)
                        
// 返回两个日期时间值之间的持续时间(以天为单位)
MATCH (x:Test {id: 1})
RETURN duration.inDays(x.datetime1,x.datetime2).days
                       
// 添加6个月的持续时间
MATCH (x:Test {id: 1})
RETURN x.date1 + duration({months: 6})

使用APOC设置日期和时间格式

MATCH (x:Test {id: 1})
RETURN x.datetime as Datetime,
apoc.temporal.format( x.datetime, 'HH:mm:ss.SSSS')
AS formattedDateTime

// 结果
"2022-08-22T08:13:37.150000000Z"
"08:13:37.1500"

APOC转换为另一日期格式

MATCH (x:Test {id: 1})
RETURN apoc.date.toISO8601(x.datetime.epochMillis, "ms")
AS iso8601

使用格式字符串分析任意格式化时态值。apoc.temporal.toZonedTemporal()

图形遍历–查询性能

图形遍历,最重要的是:让查询更具性能优化

查询锚点(可理解为节点)

单个锚点

锚点通常由存储在图形中的元数据或内联或子句中提供的筛选器确定。

查询的定位点将基于需要检索到内存中的最少节点数。

多个锚点

默认情况下,一组锚点节点由与查询路径和用于筛选查询的子句相关的元数据确定。在某些情况下,您可能有多个锚点节点集

PROFILE
MATCH (p1:Person)-[:ACTED_IN]->(m1)
MATCH (m2)<-[:ACTED_IN]-(p2:Person)
WHERE p1.name = 'Tom Hanks'
AND p2.name = 'Meg Ryan'
AND m1 = m2
RETURN m1.title

// 在此查询中,将检索所有 p1 节点以及所有 p2 节点。此查询有两组锚点节点。它在应用相等性筛选器之前检索锚点节点。查询计划程序会尝试尽早应用筛选器以减少基数(行数)。

路径展开

作为定位点集一部分的已加载的初始节点具有指向关系的指针,这些关系指向关系另一端的节点。

在查询时添加路径,可加快查询效率

基本查询遍历–深度优先

相同查询下,第一种查询比第二种查询更快

多模式查询遍历

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = 'Eminem'
RETURN  m.title AS movies

查询性能以及过程演示

穿越埃米纳姆的联合演员

多子句查询遍历

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = 'Eminem'
MATCH (allActors:Person)-[:ACTED_IN]->(m)
RETURN m.title AS movie, collect(allActors.name) AS allActors

查询性能以及过程演示

使用多个 Match 子句进行遍历

避免使用过多标签

图形优化

减少查询模式中使用的标签

PROFILE MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = 'Tom Hanks'
RETURN m.title AS movie

更高性能方法

PROFILE MATCH (p:Person)-[:ACTED_IN]->(m)
WHERE p.name = 'Tom Hanks'
RETURN m.title AS movie

路径查询更具优化

以下两种返回结果一致,但在性能和优化上第二种更优

MATCH (person:Person)-[]->(movie)
WHERE person.name = 'Walt Disney'
RETURN person, movie
MATCH p = ((person:Person)-[]->(movie))
WHERE person.name = 'Walt Disney'
RETURN p

路径有用的函数:

  • length(p)返回路径的长度。
  • nodes(p)返回包含路径节点的列表。
  • relationships(p)返回一个列表,其中包含路径的关系。

图形遍历–长度遍历(路径)

在Neo4j中,始终坚持关系的独特性。也就是说,两个节点之间永远不会有两个相同类型和方向的关系。这使得Neo4j能够避免图形遍历中的循环或无限循环。

最短路径

// 没有限制关系
MATCH p = shortestPath((p1:Person)-[*]-(p2:Person))
WHERE p1.name = "Eminem"
AND p2.name = "Charlton Heston"
RETURN  p

//关系类型限制为特定关系
MATCH p = shortestPath((p1:Person)-[:ACTED_IN*]-(p2:Person))
WHERE p1.name = "Eminem"
AND p2.name = "Charlton Heston"
RETURN  p

变长遍历

两个跃点(两条关系)

MATCH (p:Person {name: 'Eminem'})-[:ACTED_IN*2]-(others:Person)
RETURN  others.name

// 检索埃米纳姆人节点。
// 然后,两个ACTED_IN关系通过“电影”节点遍历 8 英里,以返回三个“人”节点。
// 然后,两个ACTED_IN关系通过Hip Hop Witch,Da的电影节点遍历,以返回三个Person节点。

距离埃米纳姆2英里的人

四个跃点(四条关系)

MATCH (p:Person {name: 'Eminem'})-[:ACTED_IN*4]-(others:Person)
RETURN  others.name
                                                 
// 检索埃米纳姆人节点。
// 然后,通过 Movie 节点遍历ACTED_IN关系,在该节点中检索 8 英里的布列塔尼·墨菲和 Little Black Book 以返回两个 Person 节点。
// 然后,四个ACTED_IN关系通过“8英里”和“预言II”的电影节点遍历,以返回两个“人”节点。
// 仅返回正好来自 Eminem 的 4 个跃点的人员节点。

距离埃米纳姆4英里的人

查询最多四跳距离

这种深度优先的遍历和检索将一直持续到检索到两个跃点和四个跃点之外的所有 Person 节点为止。

MATCH (p:Person {name: 'Eminem'})-[:ACTED_IN*1..4]-(others:Person)
RETURN  others.name
                                                   
// 检索埃米纳姆人节点。
// 然后,ACTED_IN关系通过“电影”节点遍历 8 英里和“小黑皮书”。
// 在此遍历期间,我们检索两个跃点外的 Person 节点和四个跃点外的两个 Person 节点。
// 然后,通过电影节点遍历 8 英里和预言 II 的ACTED_IN关系。
// 我们已经检索到了四个跳跃之外的布列塔尼·墨菲,但我们又添加了两个Person 节点。

距离埃米纳姆4英里的人

流水线查询

with子句定义作用域变量

使用子句定义和初始化要在查询中使用的变量。

WITH 'Tom Hanks' AS actorName
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = actorName
RETURN m.title AS movies

with重新定义范围

单子句查询

WITH  'toy story' AS mt, 'Tom Hanks' AS actorName
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = actorName
AND toLower(m.title) CONTAINS mt
RETURN m.title AS movies

多子句查询

WITH  'toy story' AS mt, 'Tom Hanks' AS actorName
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH m, toLower(m.title) AS movieTitle
WHERE p.name = actorName
AND movieTitle CONTAINS mt
RETURN m.title AS movies, movieTitle

// 变量 mt 和 actorName 可用于子句和子句,就像上一个查询一样。但是,这里的不同之处在于,我们必须将 m 添加到第二个子句中,以便可以使用该节点返回节点的标题。子句用于定义或重新定义变量的作用域。因为我们想要重新定义用于子句的内容,所以我们添加了一个新子句。这将为查询的其余部分创建一个新作用域,以便可以使用 m 和 movieTitle 返回值。如果要删除第二个子句中的 m,则查询将不会编译。

定义表达式(例如,toLower(m.title))时,必须指定使用关键字定义的别名。AS

限制结果

WITH  'Tom Hanks' AS theActor
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = theActor
RETURN m.title AS movies LIMIT 2
WITH  'Tom Hanks' AS theActor
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = theActor
WITH m  LIMIT 2
RETURN m.title AS movies

// 使用此查询,将检索两个影片节点。此处的不同之处在于,您可以使用来限制稍后在查询中使用的 m 个节点数。将节点传递到下一个子句称为流水线

对限制结果进一步处理,进行排序

WITH  'Tom Hanks' AS theActor
MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = theActor
WITH m ORDER BY m.year LIMIT 5
RETURN m.title AS movies, m.year AS yearReleased

with自定义返回节点属性

MATCH (n:Movie)
WHERE n.imdbRating IS NOT NULL
AND n.poster IS NOT NULL
WITH n {
  .title,
  .year,
  .languages,
  .plot,
  .poster,
  .imdbRating,
  directors: [ (n)<-[:DIRECTED]-(d) | d { tmdbId:d.imdbId, .name } ]
}
ORDER BY n.imdbRating DESC LIMIT 4
RETURN collect(n)

此查询返回“影片”节点中的数据子集。它返回评分最高的四部电影。由于我们已指定 4 个限制,因此只有 4 个具有指定属性的对象添加到列表中。

虽然这非常适合在客户端进行处理,但它会在服务器上占用更多内存,因为记录无法流式传输到客户端,而是收集到服务器上的列表结构中。

with流水线查询

使我们能够将第一个查询的结果管道化到第二个查询中。通过这个简单的查询,m 不需要重新定义或限定范围。

聚合

MATCH (:Movie {title: 'Toy Story'})-[:IN_GENRE]->(g:Genre)<-[:IN_GENRE]-(m)
WHERE m.imdbRating IS NOT NULL
WITH g.name AS genre,
count(m) AS moviesInCommon,
sum(m.imdbRating) AS total
RETURN genre, moviesInCommon,
total/moviesInCommon AS score
ORDER By score DESC

聚合、流水线

MATCH (u:User {name: "Misty Williams"})-[r:RATED]->(:Movie)
WITH u, avg(r.rating) AS average
MATCH (u)-[r:RATED]->(m:Movie)
WHERE r.rating > average
RETURN average , m.title AS movie,
r.rating as rating
ORDER BY rating DESC

2步聚合

MATCH (m:Movie)<-[:ACTED_IN]-(a:Actor)
WHERE m.title CONTAINS 'New York'
WITH m, collect (a.name) AS actors,
count(*) AS numActors
ORDER BY numActors DESC
RETURN collect(m { .title, actors, numActors }) AS movies

尽早使用LIMIT

MATCH (p:Actor)
WHERE p.born.year = 1980
WITH p  LIMIT 3
MATCH (p)-[:ACTED_IN]->(m:Movie)-[:IN_GENRE]->(g:Genre)
WITH p, collect(DISTINCT g.name) AS genres
RETURN p.name AS actor, genres

unwind展开列表

UNWIND为列表的每个元素返回一行。
如:某节点有个属性为列表,UNWIND将列表中的元素迭代,每个元素返回一个结果

MATCH (m:Movie)-[:ACTED_IN]-(a:Actor)
WHERE a.name = 'Tom Hanks'
UNWIND m.languages AS lang
RETURN m.title AS movie,
m.languages AS languages,
lang AS language

// 一部汤姆·汉克斯(Tom Hanks)出演的电影被检索到。
// 语言属性(即列表)被解包,并且每个值都被引用为 lang。
// 返回的行将是电影标题和为多行重复的语言属性以及 lang 值。
// 检索所有影片节点。
// 对于每个“电影”节点,它会展开语言列表以创建一个名为 lang 的列表。请注意,我们使用 trim() 函数来确保语言名称中没有多余的空格字符。
// 然后,我们使用列表的元素来查找使用该语言的所有电影。
// 最后,我们返回一行,其中包含每种语言名称以及该语言的最多 10 个电影标题的列表。
MATCH (m:Movie)
UNWIND m.languages AS lang
WITH m, trim(lang) AS language
WITH language, collect(m.title) AS movies
RETURN language, movies[0..10]

trim() 函数来确保语言名称中没有多余的空格字符。

优化查询,减少内存

子查询

执行一系列子句时,检索到的所有节点和关系都在内存中。如果一组子句的内存要求超过配置的 VM,则查询将失败。

子查询是一组在其自己的范围内执行的 Cypher 语句。子查询通常从外部封闭查询调用。使用子查询,可以限制需要处理的行数。

以下是有关子查询的一些重要事项:

  • 子查询返回子句中的变量所引用的值。
  • 子查询不能返回与封闭查询中使用的同名的变量。
  • 必须将变量从封闭查询显式传递到子查询。

CALL执行子查询

子查询由此处的 {}分隔
CALL {
   MATCH (m:Movie) WHERE m.year = 2000
   RETURN m ORDER BY m.imdbRating DESC LIMIT 10
}
MATCH  (:User)-[r:RATED]->(m)
RETURN m.title, avg(r.rating)
变量传递子查询

使用子查询可以减少查询中处理的行数

MATCH (m:Movie)
CALL {
    WITH m
    MATCH (m)<-[r:RATED]-(u:User)
     WHERE r.rating = 5
    RETURN count(u) AS numReviews
}
RETURN m.title, numReviews
ORDER BY numReviews DESC

// 第一个为每部电影返回一行,图中的 m。MATCH
// 它将 Movie 节点 m 传递给子查询。
// 然后在子查询中,执行查询以查找给予该电影 5 分级的所有用户,并对其进行计数。
// 子查询返回计数。
// 返回到封闭查询中,将返回标题,并从子查询返回的行数计数。

UNION查询结果结合

合并查询结果

要合并的查询必须返回相同数量的属性或数据

MATCH (m:Movie) WHERE m.year = 2000
RETURN {type:"movies", theMovies: collect(m.title)} AS data
UNION ALL
MATCH (a:Actor) WHERE a.born.year > 2000
RETURN { type:"actors", theActors: collect(DISTINCT a.name)} AS data

// 这两个查询都返回一个名为 Data 的变量,因此我们可以使用 union all 来组合结果。

UNION ALL返回所有结果,这些结果在内存上更有效,但可能导致重复。 返回不同的结果

与子查询一起用

UNION包装在子查询中,进一步处理结果

MATCH (p:Person)
WITH p LIMIT 100
CALL {
  WITH p
  OPTIONAL MATCH (p)-[:ACTED_IN]->(m:Movie)
  RETURN m.title + ": " + "Actor" AS work
UNION
  WITH p
  OPTIONAL MATCH (p)-[:DIRECTED]->(m:Movie)
  RETURN m.title+ ": " +  "Director" AS work
}
RETURN p.name, collect(work)

// 检索 100 个人员节点并将其传递到子查询。
// 如果该人在电影中表演过,则返回带有 Actor 后缀的标题。
// 子查询的第二部分对定向关系执行相同的操作。
// 合并并收集工作结果。
// 结果是该人的姓名及其演员或导演头衔。

optional match 用于搜索模式中描述的匹配项, 对于找不到的项用null代替。类似于match, 区别在于如果没有匹配到, optional match会用null来作为未匹配到的部分的值

语句参数

设置参数

单个参数

:param actorName: 'Tom Hanks'

多个参数

:params 
{
  "actorName": 'Tom Hanks'
}

设置整数

由于 JavaScript 和 Neo4j 类型系统中的整数之间存在差异,因此在设置参数时,任何整数都将转换为浮点值

:param number: 10
// 会默认将数字转换为浮点数
:param number=> 10
// 将数字强转为整数

多个参数

:params {actorName: 'Tom Cruise', movieName: 'Top Gun'}

查询

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = $actorName
AND m.title = $movieName
RETURN p, m

查看参数

:params

删除参数

:params {}

Python语法中传参示例

def get_actors(tx, movieTitle): 
  result = tx.run("""
    MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
    WHERE m.title = $title
    RETURN p
  """, title=movieTitle)

  return [ record["p"] for record in result ]

with driver.session() as session:
    result = session.read_transaction(get_actors, movieTitle="Toy Story")

总结

以上是我个人在学习过程中的记录所学,希望对正在一起学习的小伙伴有所帮助!!!

cypher更多具体用法可,跳转至官方文档查看用例

参考链接:
The Neo4j Cypher Manual
【知识图谱】Neo4j Cypher查询语言详解
[知识图谱] 3.3-Cypher语言及语法使用

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340