暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

再续前缘,Neo4j的高级语法

六只栗子 2022-11-17
1857

哈啰,各位小伙伴们,这里是每天进步一点点的花栗鼠小K

上期小K介绍了Neo4j的基础语法,本期小K想带领各位小伙伴上一个台阶,所以在这一期,我们将继续从Neo4j讲起,来介绍一些高级语法。

CQL 高级语法

  1. case 语句

    case
    条件表达式有两种,一种类似于 if/else
    ,另一种类似于 case/when

    if/else

    return
    case
    when 1=2 then 1
    when 2=2 then 2
    when 3=3 then 3
    else 4
    end

    做区间判断或者需要比较不同的字段的时候使用

    case/when 型

    return
    case 3
    when 2 then 2
    when 3 then 3
    when 4 then 4
    else 0
    end

    在使用的时候,我们常常通过match找到某个节点,对某个属性字段做不同处理

  2. 数学函数

    ABS( expression )
    返回expression得到的数值的绝对值

    ROUND( expression )
    取整函数:返回小于等于expression得到的数值的最大整数(还是返回离expression得到的数值最近的整数??)

    SQRT( expression )
    返回expression得到的数值的平方根

    SIGN( expression )
    符号函数:如果expression得到的数值,为0则返回0;为负数则返回-1;为正数则返回1

  3. 集合函数

    NODES( path )
    返回一个路径的所有节点

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    RETURN nodes(p)

    RELATIONSHIPS( path )
    返回一个路径的所有关系

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    RETURN RELATIONSHIPS(p)

    EXTRACT( identifier in collection | expression )
    返回一个结果集合:对集合(collection)的所有元素执行expression的操作得到的结果

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x
    RETURN extract(xi in x | xi.islive=false)

    FILTER(identifier in collection WHERE predicate)
    返回集合(collection)中所有满足断言(predicate)的元素组成的集合

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x

    RETURN extract(xi in x where xi.islive=false)

    ALL(identifier in collection WHERE predicate)
    当集合(collection)中所有元素满足断言(predicate) ,返回true

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x
    with all(xi in x where xi.islive=false) as result
    RETURN result

    catelyn、drogo分别对应name为Catelyn、Drogo的节点的别名

    ANY(identifier in collection WHERE predicate)
    当集合(collection)中任意一个元素满足断言(predicate) ,返回true

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x
    with any(xi in x where xi.islive=false) as result
    RETURN result

    NONE(identifier in collection WHERE predicate)
    当集合(collection)中没有一个元素满足断言(predicate) ,返回true

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x
    with none(xi in x where xi.islive=false) as result
    RETURN result

    SINGLE(identifier in collection WHERE predicate)
    如果集合(collection)里的只有一个元素满足断言(predicate)则返回true

    MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
    with nodes(p) as x
    with SINGLE(xi in x where xi.islive=true) as result
    RETURN result

    TAIL( expression )
    返回集合中除了第一个之外的所有元素

    RANGE( start, end [, step] )
    返回从start开始,end结束(闭区间)内步长为step(非0)的所有整数数字

  4. 列表

    CQL
    语言中的列表和 Python 中的列表很相似都使用 []
    ,都可以包含不同的元素,直接使用 return
    创建

    • range

      用法range(start, end, step)

    • 列表索引

      下标索引:RETURN[[1,2,3,4][1] ][] 返回2

      范围索引:RETURN [[1,2,3,4]][[1..3][1..3]  //返回[2,3],注意返回的是列表,不包括4

      范围索引:RETURN [1,2,3,4][-2..]   返回[3,4]

      越界索引:RETURN [1,2,3,4][2..9]  //只返回[3,4]

      越界索引:RETURN [1,2,3,4][7..9]  //返回一个空列表 []

      越界索引:RETURN [1,2,3,4][9]      //单个元素越界索引,返回 null

    • 列表推导

      列表推导是 Cypher 基于已有列表创建新的列表,可以和 where 等语句一起使用。功能类似于 Python 的 map 操作,也类似于 lambda 表达式,形式看起来和 linux 管道符号 |
      一样,作用也类似,前面的输出作为后面的输入。

      RETURN [x in range(1,3) | x^2]

    • 列表函数

      reverse
      :将list进行反转

      tail
      :列表的第一个元素默认为 head,tail
      函数输出除了头意外的其余函数

  5. 特殊查询

    • 省略关系

      match(n)-->(m)

      两个 -
       表示省略任意关系

      match(a:Man)-->(b:Woman)
      return a,b

    • 匹配多种关系类型

      match(n)->[:A|:B]->(m)

      匹配A或者B类型的关系

      match(a:Man)-[:I_says|:Marriage]->(b:Woman)
      return a,b

    • 带有空格的关系

      match(n)-[A B
      ]->(m)

      match(a:Man)-[`I_says Marriage`]->(b:Woman)
      return a,b

    • 变长关系

      match(n)-[r:Relationship*a..b]-(m)

      match(n:Character{name:"Eddard"})-[r:INTERACTS*1..2]-(m:Character)
      RETURN m.name

    • 最短路径

      match(n),(m),p=shortestPath((n)-[*..N]-(m))  return p

      查找 n,m 之间的最短路径,路径最大长度为N

      MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}), p=shortestPath((catelyn)-[INTERACTS*..3]-(drogo))
      RETURN p

      MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=shortestPath((catelyn)-[INTERACTS*]-(drogo))
      RETURN p

    • 所有最短路径

      match(n),(m),p=allShortestPaths((n)-[*]-(m))

      查找n,m之间所有最短路径

      MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"}),p=allShortestPaths((catelyn)-[*]-(drogo))
      RETURN p

    • id 查询

      match(n) where id(n)=1 return n

    • OPTIONAL MATCH

      可选择的 match

      match(n:Person{name:"p1"}),(m:Person{name:"p2"})   return n,m

      MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Drogo"})
      return catelyn,drogo


      MATCH (catelyn:Character {name: "Catelyn"}), (drogo:Character {name: "Loken"})
      return catelyn,drogo

      加入 OPTIONAL
      之后

      MATCH (catelyn:Character {name: "Catelyn"})
      optional match (drogo:Character {name: "Loken"})
      return catelyn,drogo

      但还是有一定的要求,match
      必须有东西

      optional MATCH (catelyn:Character {name: "Loken"})
      optional match (drogo:Character {name: "Drogo"})
      return catelyn,drogo

    • where 标签过滤

      match(n:Person) return n match(n) where labels(n)=["NodeTypeName"] return n match(n) where n:NodeTypeName return n

      match(n)
      where labels(n)=["Man"]
      return n

      match(n)
      where n:Man
      return n

    • 属性存在检查

      exists
      函数支持属性检查判断属性是否存在。 match(n) where exists (n.name) return n

      match (n:Man)
      where exists(n.name)
      return n

    • 字符串匹配

      STARTS WITH
      ENDS WITH
      CONTAINS
      支持字符串匹配(注意是大小写敏感)

      match (n:Character)
      where n.name starts with "Ca"
      return n

      match (n:Character)
      where n.name ends with "yn"
      return n

      match (n:Character)
      where n.name contains "yn"
      return n

      支持反向操作  not

    • where 路径模式

      传统的,比如查找指向凯特琳的节点,我们使用 match

      match(n:Charachter)-->(catelyn:Character{name:"Catelyn"}) return n

      如何查找都不指向凯特琳的节点呢?需要用where

    • type 匹配关系类型

      这个和 where
      标签过滤类似,但是后者是针对于节点,type
      是针对于关系标签,不支持

      match (n:Character)-[R]->(cat:Character{name:"Catelyn"})
      where TYPE(R)="INTERACTS"
      return n

    • cypher正则表达式

      cypher
      正则标识是  =~ ,‘.*’
      表示任意字符

      mysql
      中的 like,%
      表示任意长度字符,_
      表示任意单个字符

      match (n:Character)
      WHERE n.name =~".*do.*"
      return n

      因为正则表达式可能会遇到特殊字符,有时候需要转义,使用\

      CQL
      正则表达式提供了更强大的一些功能,比如不区分大小写(?i
      )、多行(?s
      )等

      match (n:Character)
      WHERE n.name =~"(?i)cat.*"
      return n

      return 'w1w2\nt3w3w4' =~ '.*w3.*'
      return 'w1w2\nt3w3w4' =~ '(?s).*w3.*'

    • 索引与约束

      添加索引:CREATE INDEX ON :label_name(property) 删除索引:DROP INDEX ON :label_name(property)

      create index on :Red_D(name)
      drop index on :Red_D(name)

      match(n:Red_D)
      WHERE n.name="贾宝玉"
      return n

      创建一个唯一约束保证图数据库中同一个标签内的节点的属性值不重复

      CREATE CONSTRAINT ON (n:NodeTypeName) ASSERT n.property IS UNIQUE
      Drop CONSTRAINT ON (n:NodeTypeName) ASSERT n.property IS UNIQUE

  6. UNWIND 和 FOREACH

    With UNWIND
    , you can transform any list back into individual rows

    unwind range(1,9,2) as x
    return x

    列表去重

    unwind [1,1,2,2,3,5] as x
    with distinct x
    return x

    遍历多个列表

    WITH [12AS a,[34AS b
    UNWIND (a + b) AS x
    RETURN x

    unwind 嵌套

    WITH [[1, 2],[3, 4], 5] AS nested
    UNWIND nested AS x
    UNWIND x AS y
    RETURN y

    空列表

    不返回任何东西,注意不是返回null。

    路径遍历

    match p=(n:Person{name:"p1"})-[*1..5]-(m)
    unwind nodes(p) as x
    return x

    The FOREACH
    clause is used to update data within a list, whether components of a path, or result of aggregation.

    MATCH p =(begin)-[*]->(END )
    WHERE begin.name = 'A' AND END .name = 'D'
    FOREACH (n IN nodes(p)| SET n.marked = TRUE )

    可以执行 CREATE UNIQUE
    , MERGE
    , DELETE
    ,等更新语法,还可做foreach嵌套。

  7. cypher 时间处理

    • date

      date函数默认返回当前时区的当前日期,如: RETURN date()   结果:"2019-05-24" 。具体使用方法如下:
      date() 当前时区当前日期
      date({ timezone: 'America/Los Angeles' }) //指定时区日期
      date({ year:1984, month:10, day:11 }) //指定日期
      date({ year:1984, week:10, dayOfWeek:3 })
      date({ year:1984, quarter:3, dayOfQuarter: 45 })
      date({ year:1984, ordinalDay:202 })
      date('2015-07-21')
      date('2015-07')
      date('201507')
      date('2015-W30-2')
      date('2015202')
      date('2015')

    • datetime

      datetime()   //当前时间
      datetime({ timezone: 'America/Los Angeles' })
      datetime({ year:1984, month:10, day:11, hour:12, minute:31, second:14, millisecond: 123, microsecond: 456, nanosecond: 789 })

  8. 嵌套查询

    简单子查询

    match (c:X_Person)
    where exists{
    match (c)-[:师傅]->(:X_Person)
    }
    return c

    带 where 的子查询

    match (c:X_Person)
    where exists{
    match (c)-[:师傅]->(:X_Person)
    where c.age>100
    }
    return c

    嵌套存在子查询

    MATCH (X:X_Person)
    WHERE EXISTS {
      MATCH (X)-[:师傅]->(Y:X_Person)
      WHERE EXISTS {
        MATCH (Y)-[:has]->(W:X_Wuqi)
        WHERE W.name = '金箍棒'
      }
    }
    RETURN X.name as name

  9. 文件的导入

    load csv with headers from "路径" as rows
    merge (head:R_D{name:rows.head})
    merge (tail:R_D{name:rows.tail})
    create (head)-[r:Red_Relation{name:rows.relation,label:rows.label}]->(tail)
    return r

总结

本期主要讲述了 Neo4j
的高级语法,从case语句到文件导入,详细地介绍 Neo4j
中高阶的命令,高阶命令是针对于更复杂场景的杀器,熟练使用高阶命令,对于处理社交网络等现实场景有很大便利,希望对感兴趣的小伙伴有所帮助。

本期就到这了,这里是花栗鼠小K,下次有🌰,我再来,拜拜~~~

关注六只栗子,面试不迷路!

作者    花栗鼠小K

编辑   一口栗子  





文章转载自六只栗子,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论