Neo4J(Cypher语句) 基础查询(一)

  • Nodes(节点)

图谱的基本单位主要是节点和关系,他们都可以包含属性,一个节点就是一行数据,一个关系也是一行数据,里面的属性就是数据库里面的row里面的字段。

除了属性之外,关系和节点还可以有零到多个标签,标签也可以认为是一个特殊分组方式。

  • Relationships(关系)

关系的功能是组织和连接节点,一个关系连接2个节点,一个开始节点和一个结束节点。当所有的点被连接起来,就形成了一张图谱,通过关系可以组织节点形成任意的结构,比如list,tree,map,tuple,或者更复杂的结构。关系拥有方向进和出,代表一种指向。

(3) Properties(属性)

属性非常类似数据库里面的字段,只有节点和关系可以拥有0到多个属性,属性类型基本和java的数据类型一致,分为 数值,字符串,布尔,以及其他的一些类型,字段名必须是字符串。

  • Labels(标签)

标签通过形容一种角色或者给节点加上一种类型,一个节点可以有多个类型,通过类型区分一类节点,这样在查询时候可以更加方便和高效,除此之外标签在给属性建立索引或者约束时候也会用到。label名称必须是非空的unicode字符串,另外lables最大标记容量是int的最大值,近似21亿。

  • Traversal(遍历)

查询时候通常是遍历图谱然后找到路径,在遍历时通常会有一个开始节点,然后根据cpyher提供的查询语句,遍历相关路径上的节点和关系,从而得到最终的结果。

  • Paths(路径)

路径是一个或多个节点通过关系连接起来的产物,例如得到图谱查询或者遍历的结果。

  • Schema(模式,类似存储数据的结构)

neo4j是一个无模式或者less模式的图谱数据库,像mongodb,solr,lucene或者es一样,你可以使用它不需要定义任何schema,

  • Indexes(索引)

遍历图通过需要大量的随机读写,如果没有索引,则可能意味着每次都是全图扫描,这样效率非常低下,为了获得更好的性能,我们可以在字段属性上构建索引,这样任何查询操作都会使用索引,从而大幅度提升seek性能,

构建索引是一个异步请求,并不会立刻生效,会再后台创建直至成功后,才能最终生效。如果创建失败,可以重建索引,先删除索引,在创建即可,然后从log里面找出创建失败的原因然后分析。

  • Constraints(约束)
    约束可以定义在某个字段上,限制字段值唯一,创建约束会自动创建索引。

cypher是neo4j官网提供的声明式查询语言,非常强大,用它可以完成任意的图谱里面的查询过滤。我现在准备探索一下neo4j的cypher查询的一些基本概念和语法。

example

参考链接Graph database concepts

Node语法
  • () 代表匹配任意一个节点
  • (node1) 代表匹配任意一个节点,并给它起了一个别名
  • (:Label) 代表查询一个类型的数据
  • (person:Label) 代表查询一个类型的数据,并给他起了一个别名
  • (person:Label {name: "小王"}) 查询某个类型下,节点属性满足某个值的数据
  • (person:Label {name:"小王", age:23}) 节点的属性可以同时存在多个,是一个AND的关系
关系语法

关系用一对一组成,关系分有方向的进和出,如果是无方向就是金河出都查询。

  • --> 指向一个节点
  • -[role]-> 给该关系加个别名
  • -[:acted_in]-> 访问某一类关系
  • -[role:acted_in] -> 访问某一类关系,并加了别名
  • -[role:acted_in{roles:["neo","Hadoop"]}]-> 访问某一类关系下的某个属性的关系的数据
模式语法

模式语法是节点和关系查询语法的结合,通过模式语法我们可以进行我们想要的任意复杂的查询。

(p1: Person:Actor {name:"tom"})-[role:acted_in {roles:["neo","actor"]}]-(m1:Movie {title:"water"})

模式变量

为了增加模块化和减少重复,cypher允许把模式的结果指定在一个变量或者别名中,方便后续使用或操作。

path = (: Person) - [: ACTED_IN] -> (:Movie)

path是结果集的抽象封装,有多个函数可以直接从path里面提取数据如:
nodes(path): 提取所有的节点
rels(path) : 提取所有的关系 和 relationships(path)相等
length(path) :获取路径的长度

条件

cypher 语句也是由多个关键词组成,像SQL

select name, count(*) from talbe where age=24 group by name having count(*) >2  order by count(*) desc

多个关键词组成的语法,cypher也非常类似,每个关键词会执行一个特定的task来处理数据
match :查询的主要关键词
create : 类似SQL里面的insert
filter, project,sort,page等都有相应的功能语句
通过组合上面的一些语句,我们可以写出非常强大复杂的语法,来查询我们需要检索的内容,cypher 会自动解析语法并优化执行。

一些实际的查询用法例子

查询

  • match (p: Person) return p; 查询Person类型的所有数据

  • match (p: Person {name:"sun"}) return p; 查询名字等于sun的人

  • match( p1: Person {name:"sun"} )-[rel:friend]->(p2) return p2.name , p2.age 查询sun的朋友的名字和年龄

  • match (old) ... create (new) create (old)-[rel:dr]->(new) return new 对已经存在的节点和新建的节点建立关系

筛选过滤
cypher过滤也是用的和SQL一样的关键词where
match (p1 : Person) where p1.name = "sun" return p1;
等同于下面的
match (p1:Person{name:"sun"}) return p1
注意where条件里面支持and,or ,xor,not等boolean运算符,在json串里面都是and,除此之外,where条件还支持正则查询。

match (p1: Person)-[r:friend]->(p2: Person) 
where p1.name=~"K.+" or p2.age=24 or "neo" in r.rels 
return p1,r,p2

关系过滤匹配使用not

MATCH (p:Person)-[:ACTED_IN]->(m)WHERE NOT (p)-[:DIRECTED]->()RETURN p,m

结果集返回

MATCH (p:Person)RETURN p, p.name AS name, upper(p.name), coalesce(p.nickname,"n/a") AS nickname, { name: p.name,  label:head(labels(p))} AS person

结果集返回做去重

match (n) return distinct n.name;

聚合函数

cypher支持count,sum,avg,min,max

match (: Person) return count(*)

聚合的时候null会被跳过 count 语法 支持 count( distinct role )

MATCH (actor:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)RETURN actor,director,count(*) AS collaborations

排序和分页

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)RETURN a,count(*) AS appearancesORDER BY appearances DESC SKIP 3 LIMIT 10;

收集聚合结果

MATCH (m:Movie)<-[:ACTED_IN]-(a:Person)
RETURN m.title AS movie, collect(a.name) AS cast, count(*) AS actors

union 联合

支持两个查询结构集一样的结果合并

MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN actor.name AS name, type(r) AS acted_in, movie.title AS title
UNION (ALL)
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN director.name AS name, type(r) AS acted_in, movie.title AS title

10, with
with语句给cypher提供了强大的pipeline能力,可以一个或者query的输出,或者下一个query的输入 和return语句非常类似,唯一不同的是,with的每一个结果,必须使用别名标识。

通过这个功能,我们可以轻而易举的做到在查询结果里面在继续嵌套查询。

MATCH (person:Person)-[:ACTED_IN]->(m:Movie)
WITH person, count(*) AS appearances, collect(m.title) AS movies
WHERE appearances > 1RETURN person.name, appearances, movies

注意在SQL里面,我们想过滤聚合结果,需要使用having语句但是在cypher里面我们可以配合with语句使用 where关键词来完成过滤

11,添加约束或者索引
唯一约束(使用merge来实现) CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.title IS UNIQUE

添加索引(在图谱遍历时,快速找到开始节点),大幅提高查询遍历性能 CREATE INDEX ON :Actor(name)

添加测试数据:

CREATE (actor:Actor { name:"Tom Hanks" }),(movie:Movie { title:'Sleepless IN Seattle' }),
  (actor)-[:ACTED_IN]->(movie);

使用索引查询:

MATCH (actor:Actor { name: "Tom Hanks" })RETURN actor;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容