Rubin's Blog

  • 首页
  • 关于作者
  • 隐私政策
享受恬静与美好~~~
分享生活的点点滴滴~~~
  1. 首页
  2. Neo4j
  3. 正文

Neo4j之CQL

2021年 11月 10日 814点热度 0人点赞 0条评论

CQL简介

CQL代表Cypher查询语言。 像关系型数据库具有查询语言SQL,Neo4j使用CQL作为查询语言。常用的Neo4j CQL命令/条款如下:

CQL命令/条作用
CREATE 创建创建节点,关系和属性
MATCH 匹配检索有关节点,关系和属性数据
RETURN 返回返回查询结果
WHERE 条件提供条件过滤检索MATCH数据
DELETE 删除删除节点和关系
REMOVE 移除删除节点和关系的属性
SET 设置添加或更新标签
ORDER BY 排序对结果排序
SKIP LIMIT 分页分页
DISTINCT 排重排重

官网文档地址:https://neo4j.com/docs/cypher-manual/4.3/introduction/。

为了完成上面的语法,我们基于庆余年电视剧人物关系图片来创建我们的测试数据:

// 删除所有的节点和关系 
 MATCH(n) OPTIONAL MATCH (n)-[r]-() DELETE n,r
// 创建Person 的节点 
CREATE (person:Person {cid:1,name:"范闲",age:24,gender:0,character:"A",money:1000,description:"范闲,是猫腻小说《庆余年》主人公,穿越人士,庆国数十年风雨画卷的见证者。其容貌俊美无双,尤胜于女子,生性淡薄刚毅,善良而腹黑,城府极深,重视恩情。最终隐居江南"});
CREATE (person:Person {cid:2,name:"林婉儿",age:20,gender:1,character:"B",money:800,description:"林婉儿是庆国宰相和长公主的私生女,电视剧《庆余年》里的女主人公,由李沁饰演"});
CREATE (person:Person {cid:3,name:"庆帝",age:49,gender:0,character:"A",money:8900,description:"庆帝,网文作家猫腻所著的权谋小说《庆余年》的角色之一,南庆国的皇帝,心中装有天下统一"});

CREATE (person:Person {cid:4,name:"长公主",age:46,gender:1,character:"B",money:3700,description:"《庆余年》中,长公主这个人不仅人设很复杂,就连她的感情生活还是挺复杂。长公主所处的身份就是庆国的公主,皇帝的妹妹,太子的姑姑,国家重要财权的掌管,林婉儿的母亲"});
CREATE (person:Person {cid:5,name:"宰相林若甫",age:47,gender:0,character:"A",money:1600,description:"林若甫,是电视剧《庆余年》登场的虚拟人物之一,南庆当朝宰相,林婉儿的亲生父亲。"});

CREATE (person:Person {cid:6,name:"叶灵儿",age:20,gender:1,character:"C",money:700,description:"叶灵儿,网文作家猫腻所著的权谋小说《庆余年》的角色之一,林婉儿的好友,最后嫁给了二皇子"});
CREATE (person:Person {cid:7,name:"九品射手燕小乙",age:47,gender:0,character:"C",money:900,description:"一品最低,九品最高。庆帝身边的燕小乙便是九品,而且是庆国独一无二的神射手,臂力、眼力、听力惊人"});
CREATE (person:Person {cid:8,name:"二皇子",age:26,gender:0,character:"B",money:1700,description:"《庆余年》中,二皇子结局自杀身亡。二皇子对庆帝也是意见很大,但以他的实力还掀不起什么水花,所以只能慢慢等待时机"});
CREATE (person:Person {cid:9,name:"靖王世子",age:25,gender:0,character:"A",money:1600,description:"在《庆余年》中,此靖王非彼靖王,但是同音之美也会让人会对靖王世子李弘成这个角色产生好感,而靖王世子李弘成的出场的确是帮助了范闲逃脱太子势力的纠缠"});
CREATE (person:Person {cid:10,name:"王启年",age:46,gender:0,character:"C",money:1700,description:"王启年,网文作家猫腻所著的权谋小说《庆余年》的角色之一,庆国监察院一处的文书,擅长追踪之术。"});
CREATE (person:Person {cid:11,name:"北齐圣女海棠朵朵",age:21,gender:1,character:"A",money:2600,description:"海棠朵朵是北齐国的才女,被人尊称为圣女,而且是北齐大宗师苦荷的关门弟子,在北齐国也算是举足轻重的人物"});
CREATE (person:Person {cid:12,name:"北齐小皇帝战豆豆",age:20,gender:0,character:"A",money:4600,description:"很多人想知道剧中的北齐小皇帝是谁呢?让小编告诉你们吧。 战豆豆是北齐第二任皇帝,乃前北魏一代大将战清风之孙,大宗师苦荷的叔侄女兼徒孙"});

//创建关系 
match(person:Person {name:"范闲"}),(person2:Person {name:"林婉儿"}) create(person)-[r:Couple]->(person2);
match(person:Person {name:"范闲"}),(person2:Person {name:"王启年"}) create(person)-[r:Friends]->(person2);
match(person:Person {name:"范闲"}),(person2:Person {name:"北齐圣女海棠朵朵"}) create(person)-[r:Friends]->(person2);
match(person:Person {name:"范闲"}),(person2:Person {name:"庆帝"}) create(person)-[r:Father]->(person2);
match(person:Person {name:"范闲"}),(person2:Person {name:"长公主"}) create(person)-[r:Wife_Mother]->(person2);
match(person:Person {name:"庆帝"}),(person2:Person {name:"二皇子"}) create(person)-[r:Son]->(person2);
match(person:Person {name:"庆帝"}),(person2:Person {name:"长公主"}) create(person)-[r:BrotherSister]->(person2);
match(person:Person {name:"二皇子"}),(person2:Person {name:"靖王世子"}) create(person)-[r:Friends]->(person2);
match(person:Person {name:"北齐圣女海棠朵朵"}),(person2:Person {name:"北齐小皇帝战豆豆"}) create(person)-[r:Friends]->(person2);
match(person:Person {name:"林婉儿"}),(person2:Person {name:"叶灵儿"}) create(person)-[r:Friends]->(person2);
match(person:Person {name:"林婉儿"}),(person2:Person {name:"宰相林若甫"}) create(person)-[r:Father]->(person2);
match(person:Person {name:"林婉儿"}),(person2:Person {name:"长公主"}) create(person)-[r:Mother]->(person2);
match(person:Person {name:"长公主"}),(person2:Person {name:"九品射手燕小乙"}) create(person)-[r:Friends]->(person2);

CREATE

CREATE (
 <node-name>:<label-name>
 [{
  <property1-name>:<property1-Value>
  ........
  <propertyn-name>:<propertyn-Value>
 }]
)

语法说明:

语法元素描述
<node-name>它是我们将要创建的节点名称
<label-name>它是一个节点标签名称
<property1-name>…< propertyn-name>属性是键值对。 定义将分配给创建节点的属性的名称
<property1-value>…< propertyn-value>属性是键值对。 定义将分配给创建节点的属性的值

举例:

CREATE (person:Person)
CREATE (person:Person {cid:1,name:"范
闲",age:24,gender:0,character:"A",money:1000});
CREATE (person:Person {cid:2,name:"林婉
儿",age:20,gender:1,character:"B",money:800});
CREATE (person:Person {cid:3,name:"庆
帝",age:49,gender:0,character:"A",money:8900});

注意:这里的node-name可以理解为临时变量,它会保存在数据库里面但是不用于查询,所以节点的node-name相同不影响数据节点的创建。label-name可以理解为分类名称,这个名称很重要,之后的查询主要是用label-name来查询。

MATCH RETURN命令语法

MATCH
(
 <node-name>:<label-name>
)
RETURN
 <node-name>.<property1-name>,
 ...
 <node-name>.<propertyn-name>
语法元素描述
<node-name>它是我们将要创建的节点名称
<label-name>它是一个节点标签名称
<property1-name>…< propertyn-name>属性是键值对。 定义将分配给创建节点的属性的名称

举例:

MATCH (person:Person) return person
MATCH (person:Person) return person.name,person.age

关系创建

  • 使用现有节点创建没有属性的关系
MATCH (<node1-name>:<node1-label-name>{property1-name:property1-value,...}),(<node2-name>:<node2-label-name>{property1-name:property1-value,...})
CREATE 
(<node1-name>)-[<relationship-name>:<relationship-label-name>]->(<node2-
name>)
RETURN 相应的内容

语法说明:

语法元素描述
MATCH,CREATE,RETURN他们是Neo4J CQL关键字
<noode1-name>它用于创建关系的“From Node”的名称
<node1-label-name>它用于创建关系的“From Node”的标签名称
<node2-name>它用于创建关系的“To Node”的名称
<node2-label-name>它用于创建关系的“To Node”的标签名称
<property1-name>…< propertyn-name> 键值对名称。用于匹配查询出对应节点
<property1-value>…< propertyn-value> 键值对值。用于匹配查询出对应节点
<relationship-name>这是一个关系的名称
<relationship-label-name>它是一个关系的标签名称

示例:

创建关系
match(person:Person {name:"范闲"}) ,(person2:Person {name:"林婉儿"})
create(person)-[r:Couple]->(person2);

查询关系
match p = (person:Person {name:"范闲"})-[r:Couple]->(person2:Person) return p
match (p1:Person {name:"范闲"})-[r:Couple]-(p2:Person) return p1,p2
match (p1:Person {name:"范闲"})-[r:Couple]-(p2:Person) return r
  • 使用现有节点创建有属性的关系
MATCH (<node1-label-name>:<node1-name>),(<node2-label-name>:<node2-name>)
CREATE 
(<node1-label-name>)-[<relationship-label-name>:<relationship-name>
{<define-properties-list>}]->(<node2-label-name>)
RETURN <relationship-label-name>
其中<define-properties-list> 是分配给新创建关系的属性(名称 - 值对)的列表。
{
 <property1-name>:<property1-value>,
 <property2-name>:<property2-value>,
 ...
 <propertyn-name>:<propertyn-value>
}

示例:

MATCH (person:Person {name:"范闲"}),(person2:Person {name:"林婉儿"})
CREATE (person)-[r:Couple{mary_date:"12/12/2014",price:55000}]->(person2)
RETURN r
  • 使用新节点创建没有属性的关系
CREATE 
(<node1-name>:<node1-label-name>)
-[<relationship-name>:<relationship-label-name>]->
(<node1-name>:<node1-label-name>)

示例如下:

CREATE (person1:Person {cid:4,name:"长公
主",age:49,gender:1,character:"A",money:5000})
-[r:Friend]->
(person2:Person {cid:7,name:"九品射手燕小
乙",age:48,gender:0,character:"B",money:1000})
  • 使用新节点创建有属性的关系
CREATE (<node1-name>:<node1-label-name>) -[<relationship-name>:<relationship-label-name>{<define-properties-list>}]-> (<node1-name>:<node1-label-name>)

示例:

CREATE (person1:Person {cid:9,name:"靖王世
子",age:23,gender:0,character:"A",money:3000})
-[r:Friend {date:"11-02-2000"}]->
(person2:Person {cid:8,name:"二皇子",age:24,gender:0,character:"B",money:6000})

关系和节点的属性可以使用的类型:

CQL数据类型作用
boolean它用于表示布尔文字:true, false
byte它用来表示8位整数
short它用于表示16位整数
int它用于表示32位整数
long它用于表示64位整数
float浮点数用于表示32位浮点数
doubleDouble用于表示64位浮点数
charChar用于表示16位字符
String字符串用于表示字符串

CREATE创建多个标签

CREATE (<node-name>:<label-name1>:<label-name2>.....:<label-namen>)
如:
CREATE (person:Person:Beauty:Picture {cid:20,name:"小美女"})

WHERE子句

简单的WHERE子句
WHERE <condition>
复杂的WHERE子句
WHERE <condition> <boolean-operator> <condition>

WHERE中的比较运算符和之前MySQL的相同。如 = 、!=、 >、< 等。

布尔运算符描述
AND与
OR或
NOT非

示例:

MATCH (person:Person)
 
WHERE person.name = '范闲' OR person.name = '靖王世子'
RETURN person

DELETE子句和REMOVE子句

DELETE子句

  • 删除节点
  • 删除节点及相关节点和关系
MATCH p = (:Person {name:"林婉儿"})-[r:Couple]-(:Person) 
DELETE r

REMOVE子句

  • 删除节点或关系的标签
  • 删除节点或关系的属性
MATCH (person:Person {name:"小美女"})
REMOVE person.cid

SET子句

  • 向现有节点或关系添加新属性
  • 更新属性值
MATCH (person:Person {cid:1})
SET person.money = 3456,person.age=25

ORDER BY子句

ORDER BY子句,对MATCH查询返回的结果进行排序。我们可以按升序或降序对行进行排序。默认情况下,它按升序对行进行排序。 如果我们要按降序对它们进行排序,我们需要使用DESC子句。

MATCH (person:Person)
RETURN person.name,person.money
ORDER BY person.money DESC

SKIP和LIMIT

Neo4j CQL已提供SKIP子句来过滤或限制查询返回的行数。 它修整了CQL查询结果集顶部的结果。

Neo4j CQL已提供LIMIT子句来过滤或限制查询返回的行数。 它修剪CQL查询结果集底部的结果。

MATCH (person:Person)
RETURN ID(person),person.name,person.money
ORDER BY person.money DESC  
SKIP 4 LIMIT 2

DISTINCT排重

这个函数的用法就像SQL中的DISTINCT关键字,返回的是所有不同值。

MATCH (p:Person) 
RETURN DISTINCT(p.character)

CQL函数

字符串函数

功能描述
UPPER它用于将所有字母更改为大写字母
LOWER它用于将所有字母改为小写字母
SUBSTRING它用于获取给定String的子字符串
REPLACE它用于替换一个字符串的子字符串
MATCH (p:Person)
RETURN ID(p),LOWER(p.character)
MATCH(p:Person) 
RETURN
 p.character,LOWER(p.character),p.name,SUBSTRING(p.name,2),REPLACE(p.name,"子","z
i")

聚合函数

聚集功能描述
COUNT它返回由MATCH命令返回的行数
MAX它从MATCH命令返回的一组行返回最大值
MIN它返回由MATCH命令返回的一组行的最小值
SUM它返回由MATCH命令返回的所有行的求和值
AVG它返回由MATCH命令返回的所有行的平均值
MATCH (p:Person)
RETURN MAX(p.money),SUM(p.money)

关系函数

功能描述
STARTNODE它用于知道关系的开始节点
ENDNODE它用于知道关系的结束节点
ID它用于知道关系的ID
TYPE它用于知道字符串表示中的一个关系的TYPE
MATCH p = (:Person {name:"林婉儿"})-[r:Couple]-(:Person)
RETURN STARTNODE(r)

shortestPath函数

该函数用于返回最短的path。示例如下:

MATCH p=shortestPath( (node1)-[*]-(node2) )
RETURN length(p), nodes(p)
MATCH p=shortestPath((person:Person {name:"王启年"})-[*]-(person2:Person
{name:"九品射手燕小乙"}) ) 
RETURN length(p), nodes(p)

CQL多深度关系节点

使用with关键字

查询三层级关系节点如下:with可以将前面查询结果作为后面查询条件

MATCH (na:Person)-[re]->(nb:Person) 
WHERE na.name="范闲" 
WITH na,re,nb 
MATCH (nb:Person)-
[re2]->(nc:Person)
RETURN na,re,nb,re2,nc

MATCH (na:Person)-[re]->(nb:Person) 
WHERE na.name="林婉儿" 
WITH na,re,nb 
MATCH (nb:Person)-
[re2]->(nc:Person) 
RETURN na,re,nb,re2,nc

MATCH (na:Person)-[re]-(nb:Person) 
WHERE na.name="林婉儿" 
WITH na,re,nb 
MATCH (nb:Person)-
[re2]->(nc:Person) 
RETURN na,re,nb,re2,nc

MATCH (na:Person)-[re]-(nb:Person) 
WHERE na.name="林婉儿" 
WITH na,re,nb 
MATCH (nb:Person)-
[re2:Friends]->(nc:Person) 
RETURN na,re,nb,re2,nc

直接拼接关系节点查询

MATCH (na:Person{name:"范闲"})-[re]->(nb:Person)-[re2]->(nc:Person) 
RETURN na,re,nb,re2,nc

为了方便,可以将查询结果赋给变量,然后返回

MATCH data=(na:Person{name:"范闲"})-[re]->(nb:Person)-[re2]->(nc:Person) 
RETURN data

使用深度运算符

当实现多深度关系节点查询时,显然使用以上方式比较繁琐。

深度查询表达式如下:

节点1-[:TYPE*minHops..maxHops]->节点2

示例:

MATCH (charlie {name: 'Charlie Sheen'})-[:ACTED_IN*1..3]-(movie:Movie)
RETURN movie.title

上述示例指的是查询 charlie 节点到movie节点1到3层关系,且关系标签为ACTED_IN的电影名称。

详细可以参考官方文档:https://neo4j.com/docs/cypher-manual/4.3/clauses/match/#rel-types-with-uncommon-chars。

事务

为了保持数据的完整性和保证良好的事务行为,Neo4j也支持ACID特性 。

注意:

  • 所有对Neo4j数据库的数据修改操作都必须封装在事务里
  • 默认的isolation level是READ_COMMITTED
  • 死锁保护已经内置到核心事务管理 。 (Neo4j会在死锁发生之前检测死锁并抛出异常。在异常抛出之前,事务会被标志为回滚。当事务结束时,事务会释放它所持有的锁,则该事务的锁所引起的死锁也就是解除,其他事务就可以继续执行。当用户需要时,抛出异常的事务可以尝试重新执行
  • 除特别说明,Neo4j的API的操作都是线程安全的,Neo4j数据库的操作也就没有必要使用外部的同步方法

索引

简介

Neo4j CQL支持节点或关系属性上的索引,以提高应用程序的性能。可以为具有相同标签名称的属性上创建索引。可以在MATCH或WHERE等运算符上使用这些索引列来改进CQL 的执行。

创建单一索引

CREATE INDEX ON :Label(property)

例如:

CREATE INDEX ON :Person(name)

创建复合索引

CREATE INDEX ON :Person(age, gender)

全文模式索引

之前的常规模式索引只能对字符串进行精确匹配或者前后缀索引(startswith,endswith,contains),全文索引将标记化索引字符串值,因此它可以匹配字符串中任何位置的术语。索引字符串如何被标记化并分解为术语,取决于配置全文模式索引的分析器。索引是通过属性来创建,便于快速查找节点或者关系。

创建全文模式索引:

call db.index.fulltext.createNodeIndex("索引名",[Label,Label],[属性,属性])

call db.index.fulltext.createNodeIndex("nameAndDescription",["Person"],["name",
"description"])

call db.index.fulltext.queryNodes("nameAndDescription", "范闲") YIELD node, score
RETURN node.name, node.description, score

查看和删除索引

查看索引
call db.indexes
或者
:schema

删除索引
DROP INDEX ON :Person(name)
DROP INDEX ON :Person(age, gender)
call db.index.fulltext.drop("nameAndDescription")

约束

唯一性约束

CREATE CONSTRAINT ON (变量:<label_name>) ASSERT 变量.<property_name> IS UNIQUE

具体实例:

CREATE CONSTRAINT ON (person:Person) ASSERT person.name IS UNIQUE

删除唯一性约束:

DROP CONSTRAINT ON (cc:Person) ASSERT cc.name IS UNIQUE

属性存在约束 (企业版中可用)

CREATE CONSTRAINT ON (p:Person) ASSERT exists(p.name)

查看约束

call db.constraints

或者
:schema

以上就是本文的全部内容。欢迎各位小伙伴积极留言交流~~~

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: Neo4j
最后更新:2022年 6月 9日

RubinChu

一个快乐的小逗比~~~

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复
文章目录
  • CQL简介
  • CREATE
  • MATCH RETURN命令语法
  • 关系创建
  • CREATE创建多个标签
  • WHERE子句
  • DELETE子句和REMOVE子句
    • DELETE子句
    • REMOVE子句
  • SET子句
  • ORDER BY子句
  • SKIP和LIMIT
  • DISTINCT排重
  • CQL函数
    • 字符串函数
    • 聚合函数
    • 关系函数
    • shortestPath函数
  • CQL多深度关系节点
    • 使用with关键字
    • 直接拼接关系节点查询
    • 使用深度运算符
  • 事务
  • 索引
    • 简介
    • 创建单一索引
    • 创建复合索引
    • 全文模式索引
    • 查看和删除索引
  • 约束
    • 唯一性约束
    • 属性存在约束 (企业版中可用)
    • 查看约束
最新 热点 随机
最新 热点 随机
问题记录之Chrome设置屏蔽Https禁止调用Http行为 问题记录之Mac设置软链接 问题记录之JDK8连接MySQL数据库失败 面试系列之自我介绍 面试总结 算法思维
网络编程详解 java并发编程之ForkJoinPool 算法之排序 Redis之快速实战 SpringBoot之源码环境搭建 Docker之docker-compose

COPYRIGHT © 2021 rubinchu.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备19039146号-1