neo4j部分文档学习

文章发布时间:

最后更新时间:

写在前面

记录一下跟着文档学习neo4j,里面会牵涉到一些在扫链子当中需要用的重要概念

MATCH

用于去匹配指定的模式

以下图中的样本图为例

image-20221108112228266

  • 基本的结点搜寻

    • 获取所有结点

      1
      2
      MATCH (n)
      RETURN n
    • 获取所有带标签的结点

      1
      2
      MATCH (movie:Movie)
      RETURN movie.title
    • 相关结点

      标志--代表中一种关联,但是忽视关联的方向类型

      1
      2
      MATCH (director {name: 'Oliver Stone'}) -- (movie)
      RETURN movie.title
    • 匹配标签

      为了利用标签模式来限制结点,在模式结点上加入标签语法

      1
      2
      MATCH (:Person {name: 'Oliver Stone'}) -- (movie:Movie)
      RETURN movie.title
  • 基本关系概念

    • 外向关系

      当关系表现出倾向性,通过--><--来表示

      1
      2
      MATCH (:Person {name: 'Oliver Stone'}) --> (movie)
      RETURN movie.title
    • 直接关系和变量

      可以通过一个变量来过滤关系的属性或者返回关系

      1
      2
      MATCH (:Person {name: 'Oliver Stone'}) -[r]-> (movie)
      RETURN type(r)

      该语句可以返回所有从Oliver发出的有向关系的类型

    • 匹配关系类型

      当你知道想要匹配的关系类型时,通过:关系类型来指定

      1
      2
      MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor)
      RETURN actor.name
    • 匹配多种关系类型

      可以将多种关系类型用|连接起来,表示匹配多种关系类型之一

      1
      2
      MATCH (wallstreet:Movie {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(actor)
      RETURN actor.name
    • 匹配关系类型并使用变量

      如果想要用变量来表示关系,且想指定想要的关系类型,都加上去即可

      1
      2
      MATCH (wallstreet {title: 'Wall Street'})<-[r:ACTED_IN]-(actor)
      RETURN r.role
  • 关系深度

    在单一模式下,关系只会被匹配一次

    • 关系类型中包含非常见字符

      有时数据库关系类型中包含非常见类型,比如空格。这时可以通过反引号`来引用

      image-20221108114733640

      例如上图中的红线,可以如下查询

      1
      2
      MATCH (n {name: 'Rob Reiner'})-[r:`TYPE INCLUDING A SPACE`]->  ()
      RETURN type(r)
    • 多重关系

      多个关系可以通过使用多个()--()形式的表达式来表示,或者直接连起来

      1
      2
      MATCH (chalie {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie)<-[:DIRECTED]-(direcotr)
      RETURN movie.title, director.name
    • 变长关系

      需要多个relationship->node模式表示的结点可以通过-[:TYPE*minHops..maxHops]->来表示,其中minHopsmaxHops是可选的,默认分别是1和无穷大。当没有给定界限时,点号可以忽略。当只有一个界限时点好也可以忽略,表示的是一个固定长度的模式

      1
      2
      MATCH (charlie {name: 'Charlie Sheen'}) -[:ACTED_IN*1..3]-(movie:Movie)
      RETURN movie.title
    • 变长多种关系

      变长关系和多种关系可组合。这样的话变长范围适用于所有结合的关系类型

      1
      2
      MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN||DIRECTED*2]-(person:Person)
      RETURN person.name
    • 可变长度关系的关系变量

      当在两节点之间的连接是可变长度时,返回的构成连接的关系列表可以如下语法表示

      1
      2
      MATCH p = (actor {name: 'Charlie Sheen'})-[:ACTED_IN*2]-(co_actor)
      RETURN relationships(p)
    • 匹配可变长路径上的属性

      变长关系上的属性意味着在路径上的所有关系都必须拥有指定的属性值。例如下图所示

      image-20221108151557440

      1
      2
      3
      MATCH p = (charlie:Person)-[* {blocked:false}]-(martin:Person)
      WHERE charlie.name = 'Charlie Sheen' AND martin.name = 'Martin Sheen'
      RETURN p

      这将返回所有在 ‘Charlie Sheen’‘Martin Sheen’之前的路径且满足属性blockedfalse

    • 零长路径

      使用下限为0的变长路径意味着两个变量可以指向同一结点。如果两节点之间的路径长度为0的话,它们就被定义为同一结点。注意到当匹配零长路径时结果即使未使用关系类型也能匹配到一个结果(即自身?)

      1
      2
      MATCH (wallstreet:Movie {title: 'Wall Street'})-[*0..1]-(x)
      RETURN x
    • 命名路径

      当想要在模式图中返回或过滤一条路径,可以引入命名路径

      1
      2
      MATCH p = (michael {name: 'Michael Douglas'})-->()
      RETURN p
    • 匹配有界关系

      当你的模式包含有界关系,而关系中并没有明确方向,Cypher会尝试双向匹配关系

      1
      2
      3
      MATCH (a)-[r]-(b)
      WHERE id(r) = 0
      RETURN a,b

      该语句会返回两个连接节点,一个是开始结点,另一个是终止结点

  • 最短路径

    • 单一最短路径

      使用函数shortestPath

      1
      2
      3
      4
      5
      MATCH 
      (martin:Person {name: 'Martin Sheen'})
      (oliver:Person {name: 'Oliver Stone'})
      p = shortestPath((martin)-[*..15]-(oliver))
      RETURN p

      这意味着:只要路径长度最大不超过15,就会在其中寻找满足的最短路径。在括号中定义了开始结点,连接关系和终止结点。在寻找最短路径时典型的描述关系的条件如关系类型,最大跳数和方向都会用上。如果在shortestPath匹配之后跟着where语句,相应的限定都会包含在寻找过程中。如果谓词是none()all(),同理。

    • 单一最短路径,带上谓词

      在最短路径模式中用上谓词WHERE也会在决定最短路径前进行评估

      1
      2
      3
      4
      5
      6
      MATCH 
      (charlie:Person {name: 'Charlie Sheen'}),
      (martin:Person {name: 'Martin Sheen'}),
      p = shortestPath((charlie)-[*]-(martin))
      WHERE none(r IN relationships(p) WHERE type(r) = 'FATHER')
      RETURN p

      不考虑父子关系

    • 所有最短路径

      寻找两节点间所有最短路径

      1
      2
      3
      4
      5
      MATCH
      (martin:Person {name: 'Martin Sheen'} ),
      (michael:Person {name: 'Michael Douglas'}),
      p = allShortestPaths((martin)-[*]-(michael))
      RETURN p
  • 通过id获得节点或关系

    • id寻找节点

      在谓词中使用id()函数可以通过id来寻找节点

      1
      2
      3
      MATCH (n)
      WHERE id(n) = 0
      RETURN n
    • id获取关系

      在谓词中使用id()函数可以通过id来寻找关系

      1
      2
      3
      MATCH ()-[r]->()
      WHERE id(r) = 0
      RETURN r
    • id寻找多个节点

      通过利用IN可以指定选择多个节点

      1
      2
      3
      MATCH (n)
      WHERE id(n) IN [0,3,5]
      RETURN n

RETURN

定义查询结果集都有什么

image-20221108162123160

  • 返回节点

    直接列举在RETURN陈述句当中即可

    1
    2
    MATCH (n {name: 'B'})
    RETURN n
  • 返回关系

    同理

    1
    2
    MATCH (n {name: 'A'})-[r:KNOWS]->(c)
    RETURN r
  • 返回属性

    利用点分隔符

    1
    2
    MATCH (n {name: 'A'})
    RETURN n.name
  • 返回所有元素

    同样支持统配符*来返回 所有结点、关系和路径

    1
    2
    MATCH p = (a {name: 'A'})-[r]->(b)
    RETURN *

    这将返回p a r b

  • 非常见字符变量

    为了引进并不是由英文字母表中元素构成的占位符(变量),可以利用`来闭合

    1
    2
    3
    MATCH (`This isn\'t a common variable`)
    WHERE `This isn\'t a common variable`.name = 'A'
    RETURN `This isn\'t a common variable`.happy
  • 字段别名

    如果字段名需要和表达式所使用的区分,可以使用AS <new name>

    1
    2
    MATCH (a {name: 'A'})
    RETURN a.age AS SomethingTotallyDifferent
  • 可选属性

    如果所指定输出的属性不存在,会返回null

  • 其他表达式

    任何表达式都可以作为返回项

    1
    2
    MATCH (a {name: 'A'})
    RETURN a.age > 30, "I'm a literal", [p=(a)-->() | p] AS `(a)-->()`
  • 唯一结果

    DISTINCT 限制了相应字段的输出结果不能重复

    1
    2
    MATCH (a {name: 'A'})-->(b)
    RETURN DISTINCT b

WHERE

image-20221108164909403

  • 基本使用

    • 布尔操作

      可以利用逻辑连接符AND OR XOR NOT

      1
      2
      3
      4
      5
      6
      MATCH(n:Person)
      WHERE n.name = 'Peter' XOR (n.age < 30 AND n.name = 'Timothy') OR NOT (n.name = 'Timothy' OR n.name = 'Peter')
      RETURN
      n.name AS name,
      n.age AS age
      ORDER BY name
    • 过滤结点标签

      WHERE后写上标签谓词n:foo, 可以过滤结点

      1
      2
      3
      MATCH (n)
      WHERE n:Swedish
      RETURN n.name, n.age
    • 过滤结点属性

      同理

      1
      2
      3
      MATCH (n:Person)
      WHERE n.age < 30
      RETURN n.name, n.age
    • 过滤关系属性

      同理

      1
      2
      3
      MATCH (n:Person)-[k:KNOWS]->(f)
      WHERE k.since < 2000
      RETURN f.name, f.age, f.email
    • 过滤动态计算属性

      当需要动态计算来过滤属性,使用方括号

      1
      2
      3
      4
      WITH 'AGE' AS propname
      MATCH (n:Person)
      WHERE n[toLower(propname)] < 30
      RETURN n.name, n.age
    • 属性存在性检查

      使用IS NOT NULL谓词来只包含属性存在的结点或关系

      1
      2
      3
      MATCH (n:Person)
      WHERE n.belt IS NOT NULL
      RETURN n.name, n.belt
    • WITH配合使用

      强调当WITH写在WHERE之前时,WHERE的作用域并不会被左右

      1
      2
      3
      4
      MATCH (n:Person)
      WITH n.name as name
      WHERE n.age = 25
      RETURN name

      WHERE仍然视为MATCH的过滤,但WITH剩余查询部分的作用范围,也就是说,name是RETURN 作用域中的唯一变量

  • 字符串匹配

    字符串前缀和后缀的匹配可以使用STARTS WITHENDS WITH . 而如果想要子串搜索,不考虑位置,用CONTAINS. 匹配时大小写敏感,如果对非字符串使用的话将会返回NULL

    • 前缀字符串搜索利用START WITH

      位置:字符串开头

      1
      2
      3
      MATCH (n:Person)
      WHERE n.name STARTS WITH 'Pet'
      RETURN n.name, n.age
    • 后缀字符串搜索利用ENDS WITH

      位置:字符串结尾

      1
      2
      3
      MATCH (n:Person)
      WHERE n.name ENDS WITH 'ter'
      RETURN n.name, n.age
    • 子串搜索利用 CONTAINS

      不管位置

      1
      2
      3
      MATCH (n:Person)
      WHERE n.name CONTAINS 'ete'
      RETURN n.name, n.age
    • 反向匹配字符串

      NOT关键字排除掉所有匹配的字符串

      1
      2
      3
      MATCH (n:Person)
      WHERE NOT n.name ENDS WITH 'y'
      RETURN n.name, n.age
  • 正规表达式

    Cypher支持正轨表达式过滤。同时支持flags标志来改变字符串的匹配方式,(?i)大小写不敏感,(?m)多行匹配,(?s)支持点号。Flags标志位放在正规表达式的开头

    • 使用正规表达式进行匹配

      语法:=~ 'regexp'

      1
      2
      3
      MATCH (n:Person)
      WHERE n.name =~ 'Tim.*'
      RETURN n.name, n.age
    • 正规表达式转义使用

      转义特殊字符. *

      1
      2
      3
      MATCH (n:Person)
      WHERE n.email =~ '.*\\.com'
      RETURN n.name, n.age, n.email
    • 大小写不敏感

      开头加?i

      1
      2
      3
      MATCH (n:Person)
      WHERE n.name =~ '(?i)AND.*'
      RETURN n.name, n.age
  • 在WHERE中使用路径模式

    • 模式过滤

      模式不仅是表达式,也是谓词。模式的唯一限制是必须能够用它来表示单一路径。不能在像用MATCH中一样用逗号分隔多种路径,可以用AND来结合。

      注意这里不能引入新的变量。WHERE字段作用是排除匹配路径。

      1
      2
      3
      4
      5
      MATCH 
      (timothy:Person {name:'Timothy'}),
      (other:Person)
      WHERE other.name IN ['Andy', 'Peter'] AND (other)-->(timothy)
      RETURN other.name, other.age
    • 模式过滤使用NOT

      作用就是排除路径

      1
      2
      3
      4
      5
      MATCH
      (person:Person),
      (peter:Person {name: 'Peter'})
      WHERE NOT (person)-->(peter)
      RETURN person.name, person.age
    • 模式过滤带上属性

      1
      2
      3
      MATCH (n:Person)
      WHERE (n)-[:KNOWS]-({name: 'Timothy'})
      RETURN n.name, n.age
    • 关系类型过滤

      可以使用特殊属性type来比较,支持正轨表达式

      1
      2
      3
      MATCH (n:Person)-[r]->()
      WHERE n.name='Andy' AND type(r) =~ 'K.*'
      RETURN type(r), r.since
  • 存在性子查询

    遇到再看

  • 列表

    • IN 操作符

      检查是否有元素存在于列表中

      1
      2
      3
      MATCH (a:Person)
      WHERE a.name IN ['Peter', 'Timothy']
      RETURN a.name, a.age
    • 错误的属性和值

      当匹配一个不存在的值时,默认为false

      如果想排除掉不存在的值,加上条件

      1
      2
      3
      4
      MATCH (n:Person)
      WHERE n.belt = 'white' OR n.belt IS NULL
      RETURN n.name, n.age, n.belt
      ORDER BY n.name
  • 范围

    • 简单的范围

      支持< <= >= >

      1
      2
      3
      MATCH (a:Person)
      WHERE a.name >= 'Peter'
      RETURN a.name, a.age
    • 复合范围

      几个不等式的组合

      1
      2
      3
      MATCH (a:Person)
      WHERE a.name > 'Andy' AND a.name < 'Timothy'
      RETURN a.name, a.age
    • 结点模式谓词

      WHERE 也可以出现在结点模式里面(MATCH语句内或模式构成当中)

      1
      2
      3
      WITH 30 AS minAge
      MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
      RETURN b.name

      注意 WHERE可以引用它所属于的结点的变量,但无法引用其他MATCH模式的变量

      1
      2
      MATCH (a:Persom {name: 'Andy'})
      RETURN [(a)-->(b WHERE b:Person) | b.name] AS friends

CALL procedure

CALL用于调用置于数据库中的程序

每一个程序调用都需要指定所需的参数。可以通过在程序名后用括号包裹逗号分隔的列表,或者通过可获得的查询参数作为调用参数。后者可以使用当且仅当所谓的独立程序调用时,整个查询构成了单一的CALL语句。

大多数程序会返回由固定结果数据集组成的记录流,与Cypher查询返回的流数据类似。YIELD子句从可获得的结果集中选择想要 返回调用程序给用户的指定变量,或者用于处理剩下的查询过程。因此,为了使用YIELD来明确字段,输出的参数名需要预知。每一个产生的结果集都可以选择性地起别名(resultFieldName AS newName. 所有由程序调用产生的新变量都会被添加到当前已在变量的作用域中。但是如果一个程序调用尝试重绑定已存在变量将会报错。在独立的程序调用中,YIELD *可用于选择全部变量。这个时候输出参数的名字就并不必要。

Neo4j支持VOID的概念。VOID程序是一个不会声明和返回结果记录的程序。因此,不允许也没必要使用YIELD.

  • 查看一个程序的特征

    当去调用一个程序时,输入参数需要知道;使用YIELD子句时,输出参数也需要知道。内置程序dbms.procedures可以返回所有程序的名字,特征和描述。

    1
    2
    3
    CALL dbms.procedures() YIELD name, signature
    WHERE name='dbms.listConfig'
    RETURN signature

    image-20221108210808878

  • 使用引用命名空间和名字调用程序

    调用内置程序db.labels可以列出数据库中的所有标签

    1
    CALL `db`.`labels`

    image-20221108211021627

  • 字面量参数调用程序

    直接在陈述句中写出即可

    1
    CALL dbms.security.createUser('example_username', 'example_password', false)
  • 使用参数来调用程序

    程序参数的值与对应传递的同名参数相一致 (没有给出的就是Null)

    传递参数的形式(如JSON) 取决于使用的驱动