美文网首页
neo4j cql语句 快速查询手册

neo4j cql语句 快速查询手册

作者: 圆企鹅i | 来源:发表于2021-01-16 21:13 被阅读0次

    前言


    和学习关系型数据库一样 neo4j最重要的当然还是写语句
    因为感觉网络上的文档都不好用 所以决定自己写一个
    为了查询方便 推荐使用的老哥们
    整一个浏览器的油猴插件 下个简书目录数脚本
    用起来就会丝滑很多

    image.png

    1. 快速入门

    学会这个表达式
    neo4j就已经入门了
    ( )代表一个点 , [ ]代表一个关系

    ()-[]-()
    

    创建一个叫list 的ArrayList的点 ↓
    等于ArrayList<?> list = new ArrayList<>()
    一个叫map的HashMap的关系↓
    基本上就等于HashMap<?,?> map = new HashMap<>();
    map 这个名称只是临时定义 方便后面可以增加return/delete之类的操作

    (list:ArrayList)
    [map:HashMap]
    

    一个叫list 的ArrayList的点 他具有size=10 ,value="1 2 3 4 5"的属性
    一个叫map的HashMap的关系 他具有size=20, value="<abc:def>"的属性

    (list:ArrayList{size:10,value:"1 2 3 4 5"})
    [map:HashMap{size:20,value:"<abc:def>"}]
    

    运行

    create
    (list:ArrayList{size:10,value:"1 2 3 4 5"})
    -[map:HashMap{size:20,value:"<abc:def>"}]->
    (list2:ArrayList{size:10,value:"1 2 3 4 5"})
    return list,map,list2
    
    image.png

    <id>是neo4j产生的唯一id,ArrayList是你给这个对象创建的类


    image.png

    还记得多少?
    嗯?什么?全不记得了?
    好的 那么你已经学会了太极拳(neo4j)/doge


    2. 基本语句

    2.1 NODE CREATE 创建

    创建猫节点
    CREATE (<node-name>:<label-name>)
    create (小黑:cat)
    
    书写规则
    CREATE (
       <node-name>:<label-name>
       {    
          <Property1-name>:<Property1-Value>
          ........
          <Propertyn-name>:<Propertyn-Value>
       }
    )
    创建一个cat节点定义...属性
    CREATE (小小黑:cat{ id:001,name:"ssBlack",age:"3" })
    
    
    设置cat节点具有的属性(不设置创建节点会自动生成)
    create (cat:cid:name:age:gender:class)
    
    image.png
    可以看出(<node-name>:<label-name>)小小黑(node-name)没有什么用

    2.2 NODE MATCH查询

    查询猪妈妈相关的所有信息
    match (猪妈妈:pig) return 猪妈妈
    
    查询年龄为11的小猪
    match (p:pig{age:11})return p
    
    查询叫佩奇性别为女的小猪
    match (p:pig)
    where p.name="佩奇"
    and p.gender="girl"
    return p
    
    查询age =11或者name=猪爸爸的节点
    match (p:pig)
    where p.age =11 or p.name="猪爸爸"
    return p
    
    image.png

    2.3 NODE MATCH&RETURN数据表格

    数据表格

    查询所有小猪的姓名和年龄
    match (p:pig)
    return p.name,p.age
    
    image.png
    查询person具有哪些关系 关系名叫啥
    match (a:person)-[r]->(b)
    return r,type(r)
    
    image.png

    /doge

    查询小红帽混乱的人物关系
    match (a:person{name:"小红帽"})-[r]->(b)
    return a,b,r,type(r)
    
    image.png

    2.4 NODE DELETE删除

    ps:删除点的时候 如果存在关系的话 删不掉 得先删除关系

    #创建一个showmaker节点 写上他的信息
    create (e:showmaker{name:"faker",id:001})
    return e
    #detach 可以删除改点的相关关系 然后删除点(常用)
    match (a:showmaker)  detach delete a  return a
    
    #删除所有showmaker节点
    match (a:showmaker)
    delete a
    return a
    
    查询一个showmaker名字叫做777
    match (e:showmaker)
    where e.name="777"
    return e
    
    稍微改装一下 就是删除
    match (e:showmaker)
    where e.name="777"
    delete e
    

    由此我们更加可以看出 e(node-name)是用来作为调用使用的 类似于指针 或者说别名


    ps :Edge/Relationship =边/关系)


    2.5 EDGE CREATE创建

    create (c:cat{cid:001,name:"罗小黑",cid:001,age:12})
    
    创建一个cat和pig的关系(等同于java创建空对象)
    CREATE (n1:cat)-[r1:likes]->(n2:pig)
    
    image.png
    给狼人(wolf)-和->村长(sheep)创建关系
    match (s1:sheep),(w1:wolf)
    where s1.name="村长" and w1.name="狼人"
    create (w1)-[r:`狼人杀`{type:"game",time:"2021/1/16"}]->(s1)
    return r
    
    万一添加错了删掉
    match (s1:sheep),(w1:wolf)
    where s1.name="村长" and w1.name="狼人"
    optional match s1-[r]->w1
    delete r
    
    image.png

    嗨呀 一不小心就透露了删除边的写法

    2.6 MERGE 如果不存在就创建

    merge会自动根据id去重 ,重复属性id值的 不会添加

    image.png

    如图我们发现只有faker在

    #创造7酱!
    merge(n:showmaker{id:2,name:"777"})
    
    image.png

    再次创造7酱! 已经存在了 就不能创造了


    image.png

    2.7 EDGE DELETE 删除

    相关的节点关系全部删除
    MATCH (cc: CreditCard)-[rel]-(c:Customer) 
    DELETE cc,c,rel
    
    image.png
    用楼上的方法 会删除所有->和查询条件相符的关系 
    当时只需要删除一个的时候可以使用关系的唯一id(不是自己设置的属性,neo4j自带的唯一标识)
    
    match ()-[r]->()
    where id(r)=125
    delete r
    

    2.8 REMOVE删除属性

    #查看该点的信息
    match (s:showmaker{id:1})
    return s
    
    image.png
    #删掉该点的id信息
    match (s:showmaker{id:1})
    remove s.id
    return s
    
    image.png

    2.9 SET设置/更新属性

    想变回来怎么办

    #恢复刚刚的点信息
    match (n:showmaker {name:"faker"})
    set n = {name:"faker",id:1}
    return n 
    
    image.png

    加上给所有该label的点添加属性

    # 给每个学生 添加上木叶村属性
    match (student:Student)
    set student.country = "木叶"
    return student
    
    

    2.10 LIMIT&SKIP截取和跳过

    原理和上一篇stream流一样
    过于简单就不说了


    image.png

    我个人觉得和排序一起用会比较爽

    #根据年龄正序排列 但是去掉前面两个
    MATCH (n:pig) 
    return n.name, n.age
    order by n.age asc
    skip 2
    
    image.png

    2.11 分页

    利用skip和limit我们很容易就达成分页了啦
    skip=page*pagesize //当前页X每页条数
    limit=pagesize //每页条数

    #每页两个数据 当前第三页
    MATCH (n:pig) 
    return n.name, n.age
    order by n.age asc
    skip 4
    limit 2
    
    image.png

    2.12 NULL 空属性

    neo4j是允许属性为空的

    创建一个点但是不设置任何属性
    create (a:showmaker)
    

    当当! 就会出现这么一个鬼东西

    image.png
    is not null 自如其名
    查询不为空的点
    MATCH (n:showmaker) 
    where n  is not null
    RETURN n LIMIT 25
    

    我们可以发现 这个点是存在的 只是属性没有而已


    image.png

    查询属性为空的点

    查询name属性不为空的点
    MATCH (n:showmaker) 
    where n.name  is not null
    RETURN n LIMIT 25
    

    就可以筛选掉某些属性为空的数据

    image.png
    通常我们用java的话 就可以通过语句
    减少在neo4j中获取的空数据
    就不用去java里面判空了 也减少了数据库连接中传输数据的大小
    image.png

    2.13 IN 范围查询

    道理和sql差不多 规范是 in [a , b, c]

    查询年龄在100 60 55的小猪
    match (a:pig)
    where a.age in [100,60,55]
    return a
    
    image.png

    2.14 排序order by

    老排序了 和sql一样用

    # 正序排列
    match (w:wolf)
    return w.name, w.age
    order by w.age asc
    
    image.png
    #倒序排列
    match (w:wolf)
    return w.name, w.age
    order by w.age desc
    
    image.png

    2.15 = ~".* XXX .*" 模糊查询

    neo4j里面规定的like写法有点奇怪
    = ~".* XXX .*"

    查询*太*的点信息
    match (a)
    where a.name =~".*太.*"
    return a
    

    查询结果:


    image.png
    image.png

    2.15 逻辑运算,等于,不等于,与或非,异或

    image.png image.png

    3. CQL函数

    3.1 字符串函数

    不多说什么了 neo4j是java写的 懂的都懂/doge

    3.1.1 UPPER&LOWER字母大小写

    把name变成大写
    MATCH (n:showmaker) 
    RETURN n.id,upper(n.name )as name
    LIMIT 25
    
    image.png

    3.1.2 SUBSTRING截取

    ps:左闭右开

    把spring截取faker [0,2)左闭右开
    MATCH (n:showmaker) 
    RETURN n.id,substring(upper(n.name),0,2)as name
    LIMIT 25
    
    image.png

    3.2 AGGREGATION聚合函数

    重点!重点!拿笔拿本子了!

    3.2.1 COUNT数量

    查询年纪在[50,80)之间的小猪的数量
    MATCH (n:pig) 
    where 80>n.age>=50 
    RETURN count(*)
    
    image.png

    ps:为了减少产生db连接而合成cql是有问题的

    这样写有问题!
    MATCH (n:pig) 
    where 80>n.age>=50 
    RETURN count(*), n
    
    image.png
    超级函数
     /**
      * 统计所有节点类型和数量 比普通查询语句速度快很多
      */
    public static final String STATISTICS_ALL_LABELS_TYPE_AND_COUNT_CQL = "call apoc.meta.stats() yield labels return labels;";
    

    3.2.2 MAX&MIN最大最小

    找出小猪最大年纪和最小年纪
    MATCH (n:pig) 
    RETURN max(n.age),min(n.age)
    
    image.png

    3.2.3 SUM&AVG求和 平均

    MATCH (n:pig) 
    RETURN sum(n.age) as sum,avg(n.age) as avg ,count(*) as count
    
    image.png

    3.3 关系函数

    3.3.1 STARTNODE&ENDNODE 开始点/结束点

    找出是对手->关系的开始点 和结束点
    match (a)-[r:`对手`]->(b)
    return startnode(r),endnode(r)
    
    image.png

    其实和return a,b结果是一样的 不知道有啥特殊的 以后知道了再写上来把

    match (a)-[r:`对手`]->(b)
    return a,b
    

    3.3.2 ID&TYPE&LABLES id和类型

    查询对手关系的id 和type 和点的类型
    match (a)-[r:`对手`]->(b)
    return id(r),type(r),labels(b)
    
    image.png

    在多个label中查询

    match (a)
    where a.id="57-(674)689-9732" and (a:user or a:contact)
    return a
    

    前者比后者快百倍

    match (n)
    where any(label in labels(n) where label in ["contact",""])
    and n.id ="57-(674)689-9732"
    return n
    

    延伸 查询节点信息

    match (a)
    where  a:contact or a:Email
    return distinct keys(properties(a))
    

    3.4 特殊函数

    FOREACH 遍历

    类似于mybatis的动态sql

    //将下列列表的人全部添加为A的朋友
    MATCH (a:Person{name:A})
    FOREACH (name IN ["Mike","Carl","Bruce"])
    CREATE (a) - [:FRIEND]->(:Person:{name:ma,e})
    

    4. 不常用分割线

    4.1 UNION不同点同时查询

    #  强行把两个节点数据 放在一张表
    match (p:person)
    return p.name as name ,p.id as id
    union
    match (s:showmaker)
    return s.name as name ,s.id as id
    
    image.png

    5.业务语句

    5.1 关系更改名字

    #修改实体label:
    match(n:oldlabel) set n:newlabel remove n:oldlabel
    
    #修改关系label(将关系subord 修改为 subord_new):
    MATCH p=(n:User)-[r:subord]->(e:department) create(n)-[r2:subord_new]->(e)  set r2 = r with r delete r
    

    5.2 查询多级关系

    #查询喜羊羊的所有关系 直到终点
    match data = (a:Sheep{name:"喜羊羊"})-[*]->()return data
    
    #查询喜羊羊到别的节点 路径上所有like关系的节点
    match data = (a:Sheep{name:"喜羊羊"})-[:like*]->()return data
    
    #查询喜羊羊到别的节点 查询3个层级 路径上所有like关系的节点
    match data = (a:Sheep{name:"喜羊羊"})-[:like*1..3]->()return data
    
    #查询喜羊羊到别的节点 查询3个层级 路径上所有like关系的节点的所有两层关系节点
    match data = (a:Sheep{name:"喜羊羊"})-[:like*1..3]->()-[*1..2]-()return data
    

    apoc 查询

    match (p1)-[]-(p2)
    where p1.id in ['喜洋洋'] 
    and
    p2.id in ['灰太狼'] 
    and
    any(label in labels(p1) where label in ["Sheep"])
    and
    any(label in labels(p2) where label in ["Sheep"])
    with p1,p2
    call apoc.path.expandConfig(p1,
    {
        minLevel:0,
        maxLevel:2,
        relationshipFilter:'Friend|Like',
        endNodes:p2,
        limit:100
    })
    yield path as data return data limit 50
    

    5.3 删除所有索引

    #查看索引
    :schema
    
    #删除所有索引
    CALL apoc.schema.assert({}, {})
    

    后言

    感谢 w3cschool让我思路清晰了 很多
    https://www.w3cschool.cn/neo4j/neo4j_cql_relationship_functions.html
    感谢《Neo4j权威指南》张帜
    一直在更新 希望做出来的文档好用
    有啥觉得用着不舒服的 欢迎辱骂
    后期有空会出APOC API使用的博客 如果考完有空的话emm

    相关文章

      网友评论

          本文标题:neo4j cql语句 快速查询手册

          本文链接:https://www.haomeiwen.com/subject/aqkbaktx.html